Ecoer Logo
VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS8.63%
Net Worth
0.410USD
STEEM
3.088STEEM
SBD
0.001SBD
Effective Power
5.043SP
├── Own SP
3.972SP
└── Incoming Deleg
+1.071SP

Detailed Balance

STEEM
balance
3.088STEEM
market_balance
0.000STEEM
savings_balance
0.000STEEM
reward_steem_balance
0.000STEEM
STEEM POWER
Own SP
3.972SP
Delegated Out
0.000SP
Delegation In
1.071SP
Effective Power
5.043SP
Reward SP (pending)
0.000SP
SBD
sbd_balance
0.001SBD
sbd_conversions
0.000SBD
sbd_market_balance
0.000SBD
savings_sbd_balance
0.000SBD
reward_sbd_balance
0.000SBD
{
  "balance": "3.088 STEEM",
  "savings_balance": "0.000 STEEM",
  "reward_steem_balance": "0.000 STEEM",
  "vesting_shares": "6460.557922 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "1741.904685 VESTS",
  "sbd_balance": "0.001 SBD",
  "savings_sbd_balance": "0.000 SBD",
  "reward_sbd_balance": "0.000 SBD",
  "conversions": []
}

Account Info

namejianty
id1120438
rank217,310
reputation79155631321
created2018-09-02T15:03:24
recovery_accountsteem
proxyNone
post_count7
comment_count0
lifetime_vote_count0
witnesses_voted_for0
last_post2018-10-07T10:53:33
last_root_post2018-10-07T10:50:18
last_vote_time2018-10-07T10:51:42
proxied_vsf_votes0, 0, 0, 0
can_vote1
voting_power0
delayed_votes0
balance3.088 STEEM
savings_balance0.000 STEEM
sbd_balance0.001 SBD
savings_sbd_balance0.000 SBD
vesting_shares6460.557922 VESTS
delegated_vesting_shares0.000000 VESTS
received_vesting_shares1741.904685 VESTS
reward_vesting_balance0.000000 VESTS
vesting_balance0.000 STEEM
vesting_withdraw_rate0.000000 VESTS
next_vesting_withdrawal1969-12-31T23:59:59
withdrawn0
to_withdraw0
withdraw_routes0
savings_withdraw_requests0
last_account_recovery1970-01-01T00:00:00
reset_accountnull
last_owner_update1970-01-01T00:00:00
last_account_update1970-01-01T00:00:00
minedNo
sbd_seconds0
sbd_last_interest_payment2018-09-30T08:02:51
savings_sbd_last_interest_payment1970-01-01T00:00:00
{
  "id": 1120438,
  "name": "jianty",
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5EfxGGARU26dwpxSKL7XBufNufPjATjarqM1Cn8FAKt4wmGiQx",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM4uM3sGWPkXiTr37ruTaHTHt9tqeFpjwwmjVKcWrs1MSYMvXoEq",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5VJ6NkcFHcULd1dcxzxvZaAhEyV2nChuSnQE9GSkEjU5eJXGao",
        1
      ]
    ]
  },
  "memo_key": "STM578hgfQqUYyfcX4jKtme7q26Ng6VbCt5aEim1xatC6e2zyJzJB",
  "json_metadata": "{}",
  "posting_json_metadata": "",
  "proxy": "",
  "last_owner_update": "1970-01-01T00:00:00",
  "last_account_update": "1970-01-01T00:00:00",
  "created": "2018-09-02T15:03:24",
  "mined": false,
  "recovery_account": "steem",
  "last_account_recovery": "1970-01-01T00:00:00",
  "reset_account": "null",
  "comment_count": 0,
  "lifetime_vote_count": 0,
  "post_count": 7,
  "can_vote": true,
  "voting_manabar": {
    "current_mana": "8202462607",
    "last_update_time": 1699917039
  },
  "downvote_manabar": {
    "current_mana": 2050615651,
    "last_update_time": 1699917039
  },
  "voting_power": 0,
  "balance": "3.088 STEEM",
  "savings_balance": "0.000 STEEM",
  "sbd_balance": "0.001 SBD",
  "sbd_seconds": "0",
  "sbd_seconds_last_update": "2018-09-30T08:02:51",
  "sbd_last_interest_payment": "2018-09-30T08:02:51",
  "savings_sbd_balance": "0.000 SBD",
  "savings_sbd_seconds": "0",
  "savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
  "savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_withdraw_requests": 0,
  "reward_sbd_balance": "0.000 SBD",
  "reward_steem_balance": "0.000 STEEM",
  "reward_vesting_balance": "0.000000 VESTS",
  "reward_vesting_steem": "0.000 STEEM",
  "vesting_shares": "6460.557922 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "1741.904685 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "withdrawn": 0,
  "to_withdraw": 0,
  "withdraw_routes": 0,
  "curation_rewards": 5,
  "posting_rewards": 6178,
  "proxied_vsf_votes": [
    0,
    0,
    0,
    0
  ],
  "witnesses_voted_for": 0,
  "last_post": "2018-10-07T10:53:33",
  "last_root_post": "2018-10-07T10:50:18",
  "last_vote_time": "2018-10-07T10:51:42",
  "post_bandwidth": 0,
  "pending_claimed_accounts": 0,
  "vesting_balance": "0.000 STEEM",
  "reputation": "79155631321",
  "transfer_history": [],
  "market_history": [],
  "post_history": [],
  "vote_history": [],
  "other_history": [],
  "witness_votes": [],
  "tags_usage": [],
  "guest_bloggers": [],
  "rank": 217310
}

Withdraw Routes

IncomingOutgoing
Empty
Empty
{
  "incoming": [],
  "outgoing": []
}
From Date
To Date
steemdelegated 1.071 SP to @jianty
2023/11/13 23:10:39
delegateejianty
delegatorsteem
vesting shares1741.904685 VESTS
Transaction InfoBlock #79857616/Trx 37428906d5f7d3f41b9ecfd6a079faf27faa6820
View Raw JSON Data
{
  "block": 79857616,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "1741.904685 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-11-13T23:10:39",
  "trx_id": "37428906d5f7d3f41b9ecfd6a079faf27faa6820",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 1.404 SP to @jianty
2023/09/21 23:45:45
delegateejianty
delegatorsteem
vesting shares2283.069813 VESTS
Transaction InfoBlock #78350142/Trx 17a56603c3f422c3aafee26f77688ff308d105ae
View Raw JSON Data
{
  "block": 78350142,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "2283.069813 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-09-21T23:45:45",
  "trx_id": "17a56603c3f422c3aafee26f77688ff308d105ae",
  "trx_in_block": 3,
  "virtual_op": 0
}
steemdelegated 1.540 SP to @jianty
2022/11/03 13:18:18
delegateejianty
delegatorsteem
vesting shares2504.751251 VESTS
Transaction InfoBlock #69115173/Trx f5caef88bd215522ddeb40e85e4b12ad182a5013
View Raw JSON Data
{
  "block": 69115173,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "2504.751251 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-11-03T13:18:18",
  "trx_id": "f5caef88bd215522ddeb40e85e4b12ad182a5013",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 1.675 SP to @jianty
2022/01/17 16:41:48
delegateejianty
delegatorsteem
vesting shares2724.986387 VESTS
Transaction InfoBlock #60816268/Trx a7f0aa9c13b4f27b05236eea6f07bff379b9556d
View Raw JSON Data
{
  "block": 60816268,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "2724.986387 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-01-17T16:41:48",
  "trx_id": "a7f0aa9c13b4f27b05236eea6f07bff379b9556d",
  "trx_in_block": 7,
  "virtual_op": 0
}
steemdelegated 1.789 SP to @jianty
2021/06/14 02:17:24
delegateejianty
delegatorsteem
vesting shares2909.053140 VESTS
Transaction InfoBlock #54609484/Trx b533edfdaaca4e1aaedb7ba9f79fb9a8f8701c18
View Raw JSON Data
{
  "block": 54609484,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "2909.053140 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2021-06-14T02:17:24",
  "trx_id": "b533edfdaaca4e1aaedb7ba9f79fb9a8f8701c18",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 1.904 SP to @jianty
2020/12/11 12:34:09
delegateejianty
delegatorsteem
vesting shares3096.475114 VESTS
Transaction InfoBlock #49356882/Trx e1ed21bcecb34871e8bd6b16635843ff191ee10a
View Raw JSON Data
{
  "block": 49356882,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "3096.475114 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-11T12:34:09",
  "trx_id": "e1ed21bcecb34871e8bd6b16635843ff191ee10a",
  "trx_in_block": 3,
  "virtual_op": 0
}
steemdelegated 1.176 SP to @jianty
2020/12/06 06:10:57
delegateejianty
delegatorsteem
vesting shares1912.543513 VESTS
Transaction InfoBlock #49208437/Trx 4807683d53cb38189b1ac45aaae5d40654b4337c
View Raw JSON Data
{
  "block": 49208437,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "1912.543513 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-06T06:10:57",
  "trx_id": "4807683d53cb38189b1ac45aaae5d40654b4337c",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 1.908 SP to @jianty
2020/12/05 16:12:21
delegateejianty
delegatorsteem
vesting shares3102.682968 VESTS
Transaction InfoBlock #49191979/Trx 4409b3c22ce0ac15c6dcec0cf031471d7c2663cc
View Raw JSON Data
{
  "block": 49191979,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "3102.682968 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-05T16:12:21",
  "trx_id": "4409b3c22ce0ac15c6dcec0cf031471d7c2663cc",
  "trx_in_block": 8,
  "virtual_op": 0
}
steemdelegated 1.180 SP to @jianty
2020/11/02 18:37:15
delegateejianty
delegatorsteem
vesting shares1920.017158 VESTS
Transaction InfoBlock #48261316/Trx e82435d5cdf1163b26f5732671f8592e3639a148
View Raw JSON Data
{
  "block": 48261316,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "1920.017158 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-11-02T18:37:15",
  "trx_id": "e82435d5cdf1163b26f5732671f8592e3639a148",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 2.032 SP to @jianty
2020/05/09 07:09:48
delegateejianty
delegatorsteem
vesting shares3305.488327 VESTS
Transaction InfoBlock #43218705/Trx 27afb12df8adf7bfa573a22040eac3976bdf50ab
View Raw JSON Data
{
  "block": 43218705,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "3305.488327 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-09T07:09:48",
  "trx_id": "27afb12df8adf7bfa573a22040eac3976bdf50ab",
  "trx_in_block": 3,
  "virtual_op": 0
}
steemdelegated 1.201 SP to @jianty
2020/05/08 10:58:54
delegateejianty
delegatorsteem
vesting shares1953.311140 VESTS
Transaction InfoBlock #43195052/Trx 41ad0a2eb784066089eec9074689487fd4c85433
View Raw JSON Data
{
  "block": 43195052,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "1953.311140 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-08T10:58:54",
  "trx_id": "41ad0a2eb784066089eec9074689487fd4c85433",
  "trx_in_block": 16,
  "virtual_op": 0
}
steemdelegated 2.084 SP to @jianty
2019/12/09 04:09:42
delegateejianty
delegatorsteem
vesting shares3389.532965 VESTS
Transaction InfoBlock #38876117/Trx 6902c445c7a6e5465bc3c8961610187b227d6ad1
View Raw JSON Data
{
  "block": 38876117,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "3389.532965 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-12-09T04:09:42",
  "trx_id": "6902c445c7a6e5465bc3c8961610187b227d6ad1",
  "trx_in_block": 19,
  "virtual_op": 0
}
2019/09/03 05:39:00
authorsteemitboard
bodyCongratulations @jianty! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@jianty/birthday1.png</td><td>Happy Birthday! - You are on the Steem blockchain for 1 year!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@jianty) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=jianty)_</sub> ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authorjianty
parent permlinklatest-information-for-crypto-currency-contractnet-cnet
permlinksteemitboard-notify-jianty-20190903t053859000z
title
Transaction InfoBlock #36090649/Trx f892935fd18cc5727c5b0f9e1ec3fbf84c2f8287
View Raw JSON Data
{
  "block": 36090649,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @jianty! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@jianty/birthday1.png</td><td>Happy Birthday! - You are on the Steem blockchain for 1 year!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@jianty) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=jianty)_</sub>\n\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "jianty",
      "parent_permlink": "latest-information-for-crypto-currency-contractnet-cnet",
      "permlink": "steemitboard-notify-jianty-20190903t053859000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-09-03T05:39:00",
  "trx_id": "f892935fd18cc5727c5b0f9e1ec3fbf84c2f8287",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 2.205 SP to @jianty
2019/01/06 11:09:15
delegateejianty
delegatorsteem
vesting shares3586.536893 VESTS
Transaction InfoBlock #29216357/Trx 78d5edf5723bff84043bb88c5cf5626ad3cbaa8a
View Raw JSON Data
{
  "block": 29216357,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "3586.536893 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-06T11:09:15",
  "trx_id": "78d5edf5723bff84043bb88c5cf5626ad3cbaa8a",
  "trx_in_block": 24,
  "virtual_op": 0
}
steemdelegated 14.651 SP to @jianty
2018/10/08 16:55:12
delegateejianty
delegatorsteem
vesting shares23829.486850 VESTS
Transaction InfoBlock #26633028/Trx 948ad4017e58430c35627f9963bdf8492a02df88
View Raw JSON Data
{
  "block": 26633028,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "jianty",
      "delegator": "steem",
      "vesting_shares": "23829.486850 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-08T16:55:12",
  "trx_id": "948ad4017e58430c35627f9963bdf8492a02df88",
  "trx_in_block": 19,
  "virtual_op": 0
}
2018/10/07 12:03:57
authorabwasserrohr
bodyHey, @jianty! =) Its around 0.02$ per win (1st - 3rd). Because there aren't many players, the chances are very high to win almost every time.^^ You may see that the game entries itself are relatively high compared to the rewards, thats because we want to let the @steem.craft account grow to give bigger rewards in the future. You can also play other gametypes on the server and get higher rewards. =)
json metadata{"tags":["steemcraft"],"users":["jianty","steem.craft"],"app":"steemit/0.1"}
parent authorjianty
parent permlinkre-steemcraft-steemcraft07102018125000-20181007t105331997z
permlinkre-jianty-re-steemcraft-steemcraft07102018125000-20181007t120354751z
title
Transaction InfoBlock #26598418/Trx 2521e71930af06d38b8d448e4fc68deebcd31eb4
View Raw JSON Data
{
  "block": 26598418,
  "op": [
    "comment",
    {
      "author": "abwasserrohr",
      "body": "Hey, @jianty! =)\nIts around 0.02$ per win (1st - 3rd). Because there aren't many players, the chances are very high to win almost every time.^^\nYou may see that the game entries itself are relatively high compared to the rewards, thats because we want to let the @steem.craft account grow to give bigger rewards in the future. You can also play other gametypes on the server and get higher rewards. =)",
      "json_metadata": "{\"tags\":[\"steemcraft\"],\"users\":[\"jianty\",\"steem.craft\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "jianty",
      "parent_permlink": "re-steemcraft-steemcraft07102018125000-20181007t105331997z",
      "permlink": "re-jianty-re-steemcraft-steemcraft07102018125000-20181007t120354751z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-07T12:03:57",
  "trx_id": "2521e71930af06d38b8d448e4fc68deebcd31eb4",
  "trx_in_block": 13,
  "virtual_op": 0
}
2018/10/07 10:53:33
authorjianty
bodyNice idia. How much is the reward?
json metadata{"tags":["steemcraft"],"app":"steemit/0.1"}
parent authorsteem.craft
parent permlinksteemcraft07102018125000
permlinkre-steemcraft-steemcraft07102018125000-20181007t105331997z
title
Transaction InfoBlock #26597011/Trx 531f9ed48b7d9c845d894d521fd576f00e86d727
View Raw JSON Data
{
  "block": 26597011,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "Nice idia.\nHow much is the reward?",
      "json_metadata": "{\"tags\":[\"steemcraft\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "steem.craft",
      "parent_permlink": "steemcraft07102018125000",
      "permlink": "re-steemcraft-steemcraft07102018125000-20181007t105331997z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-07T10:53:33",
  "trx_id": "531f9ed48b7d9c845d894d521fd576f00e86d727",
  "trx_in_block": 18,
  "virtual_op": 0
}
2018/10/07 10:51:42
authorsteem.craft
permlinksteemcraft07102018125000
voterjianty
weight10000 (100.00%)
Transaction InfoBlock #26596974/Trx 0d7948dd5df2b898620136b671a88c49c0b8a428
View Raw JSON Data
{
  "block": 26596974,
  "op": [
    "vote",
    {
      "author": "steem.craft",
      "permlink": "steemcraft07102018125000",
      "voter": "jianty",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-07T10:51:42",
  "trx_id": "0d7948dd5df2b898620136b671a88c49c0b8a428",
  "trx_in_block": 33,
  "virtual_op": 0
}
2018/10/07 10:51:21
authorjianty
permlinklatest-information-for-crypto-currency-contractnet-cnet
voterzinotce
weight10000 (100.00%)
Transaction InfoBlock #26596967/Trx eda56ea00980d590e78b4ce9705a9da7eab8962d
View Raw JSON Data
{
  "block": 26596967,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "latest-information-for-crypto-currency-contractnet-cnet",
      "voter": "zinotce",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-07T10:51:21",
  "trx_id": "eda56ea00980d590e78b4ce9705a9da7eab8962d",
  "trx_in_block": 21,
  "virtual_op": 0
}
2018/10/07 10:50:18
authorjianty
body![121D8767-03F3-4A12-9ABE-F85CDABF3C9F.jpeg](https://cdn.steemitimages.com/DQmPYmCb3HqZixSJ8cNzGi6VjEqdcW86c3yUcPdixh74jBu/121D8767-03F3-4A12-9ABE-F85CDABF3C9F.jpeg) contractnet(CNET)を皆はご存知だろうか。 以下抜粋 At the intersection of Blockchain, IoT & Smart Contracts ContractNet is a public, permissionless, turing complete blockchain, aimed specifically at the implementation of smart contracts associated with IoT. It is optimized for lower memory devices. These external devices will interface directly with the ContractNet network, or with oracles acting as intermediaries between the devices and the blockchain, to securely exchange data with smart contracts on the blockchain. 今では通称、宝くじ通貨とも言われている。 https://contractnet.com 詳しい通貨の内容は公式を参考にしてほしい。 あえてピックアップするならば、CNETが一躍話題に上がった理由は「富士通」との提携だ。 しかしまだ実現はしておらず、その予定も明らかにはなっていない。 2018年3月10日からスタートした当時のICO価格ではCNETは1枚あたり約70円ほどだった。 結論から言おう、今では1円〜2円あたりの価格になっている。 最近ではCNETが取引所を実装することをアナウンスしている。 予定では11月中旬取引所開設だ。 ![EFFE7607-BF8B-436C-B5FA-83C5663E16EE.jpeg](https://cdn.steemitimages.com/DQmQrqWEfzSZFfbiehw5G2XQEQAuK1n7sXUSnwS6UZKDGx4/EFFE7607-BF8B-436C-B5FA-83C5663E16EE.jpeg) これが実現されれば、CNETの価格は今よりも上がることだろう。 1円上がるだけでかなりの利益だ。 みんなにも購入することを勧める。
json metadata{"tags":["cryptocurrency","contractnet","cnet","japanese"],"image":["https://cdn.steemitimages.com/DQmPYmCb3HqZixSJ8cNzGi6VjEqdcW86c3yUcPdixh74jBu/121D8767-03F3-4A12-9ABE-F85CDABF3C9F.jpeg","https://cdn.steemitimages.com/DQmQrqWEfzSZFfbiehw5G2XQEQAuK1n7sXUSnwS6UZKDGx4/EFFE7607-BF8B-436C-B5FA-83C5663E16EE.jpeg"],"links":["https://contractnet.com"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptocurrency
permlinklatest-information-for-crypto-currency-contractnet-cnet
title【Latest information for crypto currency】contractnet (CNET)
Transaction InfoBlock #26596946/Trx 7a2d94533bce8e7c642d0b79ae31b6b5a048691c
View Raw JSON Data
{
  "block": 26596946,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "![121D8767-03F3-4A12-9ABE-F85CDABF3C9F.jpeg](https://cdn.steemitimages.com/DQmPYmCb3HqZixSJ8cNzGi6VjEqdcW86c3yUcPdixh74jBu/121D8767-03F3-4A12-9ABE-F85CDABF3C9F.jpeg)\ncontractnet(CNET)を皆はご存知だろうか。\n\n以下抜粋\nAt the intersection of Blockchain, IoT & Smart Contracts\nContractNet is a public, permissionless, turing complete blockchain, aimed specifically at the implementation of smart contracts associated with IoT. It is optimized for lower memory devices. These external devices will interface directly with the ContractNet network, or with oracles acting as intermediaries between the devices and the blockchain, to securely exchange data with smart contracts on the blockchain.\n\n\n今では通称、宝くじ通貨とも言われている。\nhttps://contractnet.com\n\n詳しい通貨の内容は公式を参考にしてほしい。\nあえてピックアップするならば、CNETが一躍話題に上がった理由は「富士通」との提携だ。\nしかしまだ実現はしておらず、その予定も明らかにはなっていない。\n\n2018年3月10日からスタートした当時のICO価格ではCNETは1枚あたり約70円ほどだった。\n結論から言おう、今では1円〜2円あたりの価格になっている。\n\n最近ではCNETが取引所を実装することをアナウンスしている。\n予定では11月中旬取引所開設だ。\n![EFFE7607-BF8B-436C-B5FA-83C5663E16EE.jpeg](https://cdn.steemitimages.com/DQmQrqWEfzSZFfbiehw5G2XQEQAuK1n7sXUSnwS6UZKDGx4/EFFE7607-BF8B-436C-B5FA-83C5663E16EE.jpeg)\n\nこれが実現されれば、CNETの価格は今よりも上がることだろう。\n\n1円上がるだけでかなりの利益だ。\nみんなにも購入することを勧める。",
      "json_metadata": "{\"tags\":[\"cryptocurrency\",\"contractnet\",\"cnet\",\"japanese\"],\"image\":[\"https://cdn.steemitimages.com/DQmPYmCb3HqZixSJ8cNzGi6VjEqdcW86c3yUcPdixh74jBu/121D8767-03F3-4A12-9ABE-F85CDABF3C9F.jpeg\",\"https://cdn.steemitimages.com/DQmQrqWEfzSZFfbiehw5G2XQEQAuK1n7sXUSnwS6UZKDGx4/EFFE7607-BF8B-436C-B5FA-83C5663E16EE.jpeg\"],\"links\":[\"https://contractnet.com\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptocurrency",
      "permlink": "latest-information-for-crypto-currency-contractnet-cnet",
      "title": "【Latest information for crypto currency】contractnet (CNET)"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-07T10:50:18",
  "trx_id": "7a2d94533bce8e7c642d0b79ae31b6b5a048691c",
  "trx_in_block": 26,
  "virtual_op": 0
}
2018/09/30 11:11:24
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voteriflagtrash
weight-200 (-2.00%)
Transaction InfoBlock #26395896/Trx c0b4fcc172a030529f3658b3c880372a6be004ea
View Raw JSON Data
{
  "block": 26395896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "iflagtrash",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:11:24",
  "trx_id": "c0b4fcc172a030529f3658b3c880372a6be004ea",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/09/30 11:11:24
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voterrandomthoughts
weight-200 (-2.00%)
Transaction InfoBlock #26395896/Trx c0b4fcc172a030529f3658b3c880372a6be004ea
View Raw JSON Data
{
  "block": 26395896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "randomthoughts",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:11:24",
  "trx_id": "c0b4fcc172a030529f3658b3c880372a6be004ea",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/09/30 11:11:24
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voterengagement
weight-200 (-2.00%)
Transaction InfoBlock #26395896/Trx c0b4fcc172a030529f3658b3c880372a6be004ea
View Raw JSON Data
{
  "block": 26395896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "engagement",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:11:24",
  "trx_id": "c0b4fcc172a030529f3658b3c880372a6be004ea",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/09/30 11:11:24
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voterngc
weight-200 (-2.00%)
Transaction InfoBlock #26395896/Trx c0b4fcc172a030529f3658b3c880372a6be004ea
View Raw JSON Data
{
  "block": 26395896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "ngc",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:11:24",
  "trx_id": "c0b4fcc172a030529f3658b3c880372a6be004ea",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/09/30 11:11:24
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voternextgencrypto
weight-200 (-2.00%)
Transaction InfoBlock #26395896/Trx c0b4fcc172a030529f3658b3c880372a6be004ea
View Raw JSON Data
{
  "block": 26395896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "nextgencrypto",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:11:24",
  "trx_id": "c0b4fcc172a030529f3658b3c880372a6be004ea",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/09/30 11:11:24
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voterthedelegator
weight-200 (-2.00%)
Transaction InfoBlock #26395896/Trx c0b4fcc172a030529f3658b3c880372a6be004ea
View Raw JSON Data
{
  "block": 26395896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "thedelegator",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:11:24",
  "trx_id": "c0b4fcc172a030529f3658b3c880372a6be004ea",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/09/30 11:11:24
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voterthecyclist
weight-200 (-2.00%)
Transaction InfoBlock #26395896/Trx c0b4fcc172a030529f3658b3c880372a6be004ea
View Raw JSON Data
{
  "block": 26395896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "thecyclist",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:11:24",
  "trx_id": "c0b4fcc172a030529f3658b3c880372a6be004ea",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/09/30 11:10:45
authorjianty
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
voterberniesanders
weight-200 (-2.00%)
Transaction InfoBlock #26395883/Trx 7a8b5ef9d8a0d3751fc13585852d68011238cabe
View Raw JSON Data
{
  "block": 26395883,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "voter": "berniesanders",
      "weight": -200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T11:10:45",
  "trx_id": "7a8b5ef9d8a0d3751fc13585852d68011238cabe",
  "trx_in_block": 5,
  "virtual_op": 0
}
2018/09/30 08:41:21
authorjianty
bodynice post👏
json metadata{"tags":["bitshares"],"app":"steemit/0.1"}
parent authorstan
parent permlinksovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos
permlinkre-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z
title
Transaction InfoBlock #26392897/Trx d224220299e432af54b28c0572c9d154341d249b
View Raw JSON Data
{
  "block": 26392897,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "nice post👏",
      "json_metadata": "{\"tags\":[\"bitshares\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "stan",
      "parent_permlink": "sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos",
      "permlink": "re-stan-sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos-20180930t084119997z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T08:41:21",
  "trx_id": "d224220299e432af54b28c0572c9d154341d249b",
  "trx_in_block": 13,
  "virtual_op": 0
}
2018/09/30 08:39:51
authorstan
permlinksovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos
voterjianty
weight10000 (100.00%)
Transaction InfoBlock #26392867/Trx bfc6044fdf3e7569fbcb7c7cbc657dd9d84873b6
View Raw JSON Data
{
  "block": 26392867,
  "op": [
    "vote",
    {
      "author": "stan",
      "permlink": "sovereign-sky-doc-s-fictional-guide-to-the-brown-eos-beos",
      "voter": "jianty",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T08:39:51",
  "trx_id": "bfc6044fdf3e7569fbcb7c7cbc657dd9d84873b6",
  "trx_in_block": 21,
  "virtual_op": 0
}
jiantyclaimed reward balance: 3.088 STEEM, 3.848 SP
2018/09/30 08:02:51
accountjianty
reward sbd0.000 SBD
reward steem3.088 STEEM
reward vests6258.238786 VESTS
Transaction InfoBlock #26392127/Trx a8e55310646fe5464c98440a0314f01ab1211b46
View Raw JSON Data
{
  "block": 26392127,
  "op": [
    "claim_reward_balance",
    {
      "account": "jianty",
      "reward_sbd": "0.000 SBD",
      "reward_steem": "3.088 STEEM",
      "reward_vests": "6258.238786 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-30T08:02:51",
  "trx_id": "a8e55310646fe5464c98440a0314f01ab1211b46",
  "trx_in_block": 9,
  "virtual_op": 0
}
jiantyreceived 0.006 SP curation reward for @introduce.bot / introduce-bot-re-jiantybitmex-mmbot
2018/09/17 19:56:51
comment authorintroduce.bot
comment permlinkintroduce-bot-re-jiantybitmex-mmbot
curatorjianty
reward10.107986 VESTS
Transaction InfoBlock #26038153/Virtual Operation #13136
View Raw JSON Data
{
  "block": 26038153,
  "op": [
    "curation_reward",
    {
      "comment_author": "introduce.bot",
      "comment_permlink": "introduce-bot-re-jiantybitmex-mmbot",
      "curator": "jianty",
      "reward": "10.107986 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-17T19:56:51",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 13136
}
jiantyreceived 0.850 STEEM, 1.057 SP author reward for @jianty / bitmex-mmbot
2018/09/17 19:56:51
authorjianty
permlinkbitmex-mmbot
sbd payout0.000 SBD
steem payout0.850 STEEM
vesting payout1718.357647 VESTS
Transaction InfoBlock #26038153/Virtual Operation #13119
View Raw JSON Data
{
  "block": 26038153,
  "op": [
    "author_reward",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.850 STEEM",
      "vesting_payout": "1718.357647 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-17T19:56:51",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 13119
}
jiantyreceived 0.959 STEEM, 1.193 SP author reward for @jianty / 2kdc6b-bitcoin-fx
2018/09/14 15:36:06
authorjianty
permlink2kdc6b-bitcoin-fx
sbd payout0.000 SBD
steem payout0.959 STEEM
vesting payout1941.031525 VESTS
Transaction InfoBlock #25956441/Virtual Operation #9
View Raw JSON Data
{
  "block": 25956441,
  "op": [
    "author_reward",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.959 STEEM",
      "vesting_payout": "1941.031525 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-14T15:36:06",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 9
}
2018/09/11 18:23:36
authorjianty
permlink2kdc6b-bitcoin-fx
voterroelandp
weight150 (1.50%)
Transaction InfoBlock #25873420/Trx 46153f32ee4a2f27970a50091fbaa0093b111bb8
View Raw JSON Data
{
  "block": 25873420,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "roelandp",
      "weight": 150
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-11T18:23:36",
  "trx_id": "46153f32ee4a2f27970a50091fbaa0093b111bb8",
  "trx_in_block": 28,
  "virtual_op": 0
}
2018/09/11 00:23:48
authorberniesanders
permlinkget-free-byteballs-today-just-for-having-a-steem-account-usd10-80-in-free-coins
voterjianty
weight10000 (100.00%)
Transaction InfoBlock #25851831/Trx 6d6bf5740ca2be34ff55c41813d3c95acb141693
View Raw JSON Data
{
  "block": 25851831,
  "op": [
    "vote",
    {
      "author": "berniesanders",
      "permlink": "get-free-byteballs-today-just-for-having-a-steem-account-usd10-80-in-free-coins",
      "voter": "jianty",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-11T00:23:48",
  "trx_id": "6d6bf5740ca2be34ff55c41813d3c95acb141693",
  "trx_in_block": 28,
  "virtual_op": 0
}
2018/09/11 00:19:00
authorumaykl
bodyJust beastly m8
json metadata{}
parent authorjianty
parent permlinkbitmex-mmbot
permlink20180911t001901526z
title
Transaction InfoBlock #25851735/Trx 276997cd16be34071a566dfc4cbbe4ae6597e185
View Raw JSON Data
{
  "block": 25851735,
  "op": [
    "comment",
    {
      "author": "umaykl",
      "body": "Just beastly m8",
      "json_metadata": "{}",
      "parent_author": "jianty",
      "parent_permlink": "bitmex-mmbot",
      "permlink": "20180911t001901526z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-11T00:19:00",
  "trx_id": "276997cd16be34071a566dfc4cbbe4ae6597e185",
  "trx_in_block": 38,
  "virtual_op": 0
}
jiantypublished a new post: bitmex-mmbot
2018/09/11 00:13:54
authorjianty
body@@ -315,18 +315,16 @@ %E3%80%81%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AE%E6%96%B9%E3%82%82 -%E3%81%84%E3%81%84 %E6%B7%B1%E5%B1%A4%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92%E3%81%AE%E6%96%B9 @@ -501,16 +501,17 @@ %E6%9B%B8%E3%81%91%E3%81%AA%E3%81%84%E3%81%A8%E5%A7%8B%E3%82%81%E3%82%89 +%E3%82%8C %E3%81%AA%E3%81%84%E3%81%A8%E6%80%9D%E3%81%86%E3%81%AE%E3%81%A7%E3%80%81
json metadata{"tags":["bitmex","bot","japanese","jp-newbie","dqn"],"links":["https://github.com/BitMEX/sample-market-maker)","http://www.ieice.org/~prmu/jpn/ieice/2018/dt_01_004s.pdf"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitmex
permlinkbitmex-mmbot
titleBitMexのMMBotで機械学習を試みる
Transaction InfoBlock #25851633/Trx 07a0cdfbdaf93b9b663549c68dba21df0986bbc2
View Raw JSON Data
{
  "block": 25851633,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "@@ -315,18 +315,16 @@\n %E3%80%81%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AE%E6%96%B9%E3%82%82\n-%E3%81%84%E3%81%84\n %E6%B7%B1%E5%B1%A4%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92%E3%81%AE%E6%96%B9\n@@ -501,16 +501,17 @@\n %E6%9B%B8%E3%81%91%E3%81%AA%E3%81%84%E3%81%A8%E5%A7%8B%E3%82%81%E3%82%89\n+%E3%82%8C\n %E3%81%AA%E3%81%84%E3%81%A8%E6%80%9D%E3%81%86%E3%81%AE%E3%81%A7%E3%80%81\n",
      "json_metadata": "{\"tags\":[\"bitmex\",\"bot\",\"japanese\",\"jp-newbie\",\"dqn\"],\"links\":[\"https://github.com/BitMEX/sample-market-maker)\",\"http://www.ieice.org/~prmu/jpn/ieice/2018/dt_01_004s.pdf\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitmex",
      "permlink": "bitmex-mmbot",
      "title": "BitMexのMMBotで機械学習を試みる"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-11T00:13:54",
  "trx_id": "07a0cdfbdaf93b9b663549c68dba21df0986bbc2",
  "trx_in_block": 3,
  "virtual_op": 0
}
2018/09/10 19:20:18
authorsteemitboard
bodyCongratulations @jianty! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) : [![](https://steemitimages.com/70x70/http://steemitboard.com/notifications/firstcomment.png)](http://steemitboard.com/@jianty) You made your First Comment <sub>_Click on the badge to view your Board of Honor._</sub> <sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub> **Do not miss the last post from @steemitboard:** <table><tr><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/7CiQEO.png"></a></td><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07">SteemitBoard - Witness Update</a></td></tr><tr><td><a href="https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund"><img src="https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmawPYDAwfrQM8YU6ejD1f87g64cvsmEFn8RQKHJMs4zxg/image.png"></a></td><td><a href="https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund">SteemFest³ - SteemitBoard support the Travel Reimbursement Fund.</a></td></tr></table> > Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authorjianty
parent permlinkbitmex-mmbot
permlinksteemitboard-notify-jianty-20180910t192020000z
title
Transaction InfoBlock #25845765/Trx 73e11de812f4ab02e9f65baae16f1ea85cb9d884
View Raw JSON Data
{
  "block": 25845765,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @jianty! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :\n\n[![](https://steemitimages.com/70x70/http://steemitboard.com/notifications/firstcomment.png)](http://steemitboard.com/@jianty) You made your First Comment\n\n<sub>_Click on the badge to view your Board of Honor._</sub>\n<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>\n\n\n\n**Do not miss the last post from @steemitboard:**\n<table><tr><td><a href=\"https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07\"><img src=\"https://steemitimages.com/64x128/http://i.cubeupload.com/7CiQEO.png\"></a></td><td><a href=\"https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07\">SteemitBoard - Witness Update</a></td></tr><tr><td><a href=\"https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund\"><img src=\"https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmawPYDAwfrQM8YU6ejD1f87g64cvsmEFn8RQKHJMs4zxg/image.png\"></a></td><td><a href=\"https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund\">SteemFest³ - SteemitBoard support the Travel Reimbursement Fund.</a></td></tr></table>\n\n> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "jianty",
      "parent_permlink": "bitmex-mmbot",
      "permlink": "steemitboard-notify-jianty-20180910t192020000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T19:20:18",
  "trx_id": "73e11de812f4ab02e9f65baae16f1ea85cb9d884",
  "trx_in_block": 47,
  "virtual_op": 0
}
xanoxtupvoted (5.00%) @jianty / bitmex-mmbot
2018/09/10 15:42:39
authorjianty
permlinkbitmex-mmbot
voterxanoxt
weight500 (5.00%)
Transaction InfoBlock #25841413/Trx a6ef7441b5dba330f4b400f7b9b1e5c986c4ff8d
View Raw JSON Data
{
  "block": 25841413,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "xanoxt",
      "weight": 500
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T15:42:39",
  "trx_id": "a6ef7441b5dba330f4b400f7b9b1e5c986c4ff8d",
  "trx_in_block": 34,
  "virtual_op": 0
}
sumomoupvoted (7.50%) @jianty / bitmex-mmbot
2018/09/10 15:42:33
authorjianty
permlinkbitmex-mmbot
votersumomo
weight750 (7.50%)
Transaction InfoBlock #25841411/Trx 67830a84ee05c2f375fe1d2e654244cb7a65a854
View Raw JSON Data
{
  "block": 25841411,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "sumomo",
      "weight": 750
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T15:42:33",
  "trx_id": "67830a84ee05c2f375fe1d2e654244cb7a65a854",
  "trx_in_block": 11,
  "virtual_op": 0
}
steemit-jpupvoted (15.00%) @jianty / bitmex-mmbot
2018/09/10 15:42:30
authorjianty
permlinkbitmex-mmbot
votersteemit-jp
weight1500 (15.00%)
Transaction InfoBlock #25841410/Trx cf3d9c59eeb549ebeb9a5f3a20c39b2ab24076e0
View Raw JSON Data
{
  "block": 25841410,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "steemit-jp",
      "weight": 1500
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T15:42:30",
  "trx_id": "cf3d9c59eeb549ebeb9a5f3a20c39b2ab24076e0",
  "trx_in_block": 10,
  "virtual_op": 0
}
2018/09/10 14:54:24
idfollow
json["follow",{"follower":"jianty","following":"introduce.bot","what":["blog"]}]
required auths[]
required posting auths["jianty"]
Transaction InfoBlock #25840448/Trx 2a2fd750495566251f3db50aaa6cb13bba9f3b4a
View Raw JSON Data
{
  "block": 25840448,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"jianty\",\"following\":\"introduce.bot\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "jianty"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:54:24",
  "trx_id": "2a2fd750495566251f3db50aaa6cb13bba9f3b4a",
  "trx_in_block": 35,
  "virtual_op": 0
}
2018/09/10 14:54:09
authorjianty
bodyThank you!
json metadata{"tags":["bitmex"],"app":"steemit/0.1"}
parent authorintroduce.bot
parent permlinkintroduce-bot-re-jiantybitmex-mmbot
permlinkre-introducebot-introduce-bot-re-jiantybitmex-mmbot-20180910t145411107z
title
Transaction InfoBlock #25840443/Trx f1d2318e984521220ad8afd5b10881af01db3c23
View Raw JSON Data
{
  "block": 25840443,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "Thank you!",
      "json_metadata": "{\"tags\":[\"bitmex\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "introduce.bot",
      "parent_permlink": "introduce-bot-re-jiantybitmex-mmbot",
      "permlink": "re-introducebot-introduce-bot-re-jiantybitmex-mmbot-20180910t145411107z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:54:09",
  "trx_id": "f1d2318e984521220ad8afd5b10881af01db3c23",
  "trx_in_block": 42,
  "virtual_op": 0
}
2018/09/10 14:53:54
authorintroduce.bot
permlinkintroduce-bot-re-jiantybitmex-mmbot
voterjianty
weight10000 (100.00%)
Transaction InfoBlock #25840438/Trx 020147542090f43c5c28b964ab21549ee4dd8ff0
View Raw JSON Data
{
  "block": 25840438,
  "op": [
    "vote",
    {
      "author": "introduce.bot",
      "permlink": "introduce-bot-re-jiantybitmex-mmbot",
      "voter": "jianty",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:53:54",
  "trx_id": "020147542090f43c5c28b964ab21549ee4dd8ff0",
  "trx_in_block": 13,
  "virtual_op": 0
}
argonupvoted (3.00%) @jianty / bitmex-mmbot
2018/09/10 14:26:03
authorjianty
permlinkbitmex-mmbot
voterargon
weight300 (3.00%)
Transaction InfoBlock #25839881/Trx 4726c614e769b0d5847403a3d7e2e80d6001fbcc
View Raw JSON Data
{
  "block": 25839881,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "argon",
      "weight": 300
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:26:03",
  "trx_id": "4726c614e769b0d5847403a3d7e2e80d6001fbcc",
  "trx_in_block": 0,
  "virtual_op": 0
}
markandersenupvoted (100.00%) @jianty / bitmex-mmbot
2018/09/10 14:21:39
authorjianty
permlinkbitmex-mmbot
votermarkandersen
weight10000 (100.00%)
Transaction InfoBlock #25839793/Trx a7cbd47bdec4c37648122aeebdc8ca706b7bb5ed
View Raw JSON Data
{
  "block": 25839793,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "markandersen",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:21:39",
  "trx_id": "a7cbd47bdec4c37648122aeebdc8ca706b7bb5ed",
  "trx_in_block": 0,
  "virtual_op": 0
}
yohei512upvoted (100.00%) @jianty / bitmex-mmbot
2018/09/10 14:08:30
authorjianty
permlinkbitmex-mmbot
voteryohei512
weight10000 (100.00%)
Transaction InfoBlock #25839530/Trx 072bc81c5bf3a974f6d4cfe4630aba9bd06b7710
View Raw JSON Data
{
  "block": 25839530,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "yohei512",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:08:30",
  "trx_id": "072bc81c5bf3a974f6d4cfe4630aba9bd06b7710",
  "trx_in_block": 10,
  "virtual_op": 0
}
ccelesteupvoted (50.00%) @jianty / bitmex-mmbot
2018/09/10 14:02:03
authorjianty
permlinkbitmex-mmbot
votercceleste
weight5000 (50.00%)
Transaction InfoBlock #25839401/Trx acfb5436109beeb055f206c3c80f31b1d8f5f333
View Raw JSON Data
{
  "block": 25839401,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "cceleste",
      "weight": 5000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:02:03",
  "trx_id": "acfb5436109beeb055f206c3c80f31b1d8f5f333",
  "trx_in_block": 30,
  "virtual_op": 0
}
hduupvoted (2.00%) @jianty / bitmex-mmbot
2018/09/10 14:00:15
authorjianty
permlinkbitmex-mmbot
voterhdu
weight200 (2.00%)
Transaction InfoBlock #25839365/Trx 8a08276c8835314c7e9f2c85b4cc74702af682f6
View Raw JSON Data
{
  "block": 25839365,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "hdu",
      "weight": 200
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T14:00:15",
  "trx_id": "8a08276c8835314c7e9f2c85b4cc74702af682f6",
  "trx_in_block": 4,
  "virtual_op": 0
}
no0oupvoted (50.00%) @jianty / bitmex-mmbot
2018/09/10 13:58:33
authorjianty
permlinkbitmex-mmbot
voterno0o
weight5000 (50.00%)
Transaction InfoBlock #25839331/Trx f5ada35442e04b25894c6ef91c124174ac3f531d
View Raw JSON Data
{
  "block": 25839331,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "no0o",
      "weight": 5000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T13:58:33",
  "trx_id": "f5ada35442e04b25894c6ef91c124174ac3f531d",
  "trx_in_block": 18,
  "virtual_op": 0
}
vvvvvupvoted (50.00%) @jianty / bitmex-mmbot
2018/09/10 13:56:54
authorjianty
permlinkbitmex-mmbot
votervvvvv
weight5000 (50.00%)
Transaction InfoBlock #25839298/Trx aa3132c6593b7c52783aaacdcb1cb30b706535c7
View Raw JSON Data
{
  "block": 25839298,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "vvvvv",
      "weight": 5000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T13:56:54",
  "trx_id": "aa3132c6593b7c52783aaacdcb1cb30b706535c7",
  "trx_in_block": 5,
  "virtual_op": 0
}
2018/09/10 13:32:57
authorintroduce.bot
body @jianty, I gave you a vote!<br>If you follow me, I will also follow you in return!<br>Enjoy some !popcorn courtesy of @nextgencrypto!
json metadata
parent authorjianty
parent permlinkbitmex-mmbot
permlinkintroduce-bot-re-jiantybitmex-mmbot
title
Transaction InfoBlock #25838819/Trx 3100412d4bdd3affb9469a670ec34a0fcde71e21
View Raw JSON Data
{
  "block": 25838819,
  "op": [
    "comment",
    {
      "author": "introduce.bot",
      "body": " @jianty, I gave you a vote!<br>If you follow me, I will also follow you in return!<br>Enjoy some !popcorn courtesy of @nextgencrypto!",
      "json_metadata": "",
      "parent_author": "jianty",
      "parent_permlink": "bitmex-mmbot",
      "permlink": "introduce-bot-re-jiantybitmex-mmbot",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T13:32:57",
  "trx_id": "3100412d4bdd3affb9469a670ec34a0fcde71e21",
  "trx_in_block": 15,
  "virtual_op": 0
}
2018/09/10 13:32:57
authorjianty
permlinkbitmex-mmbot
voterintroduce.bot
weight100 (1.00%)
Transaction InfoBlock #25838819/Trx a87953b977e4e30d33c46154e72071be7ffb3fe3
View Raw JSON Data
{
  "block": 25838819,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "bitmex-mmbot",
      "voter": "introduce.bot",
      "weight": 100
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T13:32:57",
  "trx_id": "a87953b977e4e30d33c46154e72071be7ffb3fe3",
  "trx_in_block": 4,
  "virtual_op": 0
}
jiantypublished a new post: bitmex-mmbot
2018/09/10 13:32:51
authorjianty
body一つ前の投稿したソースだが、何故かすさまじい無駄改行の嵐で、 とてもじゃないが見れたもんじゃない。 すぐにでも消したいのにページを開くと強制ログアウトされてしまい編集ができないという謎の減少が起きている。。 ということで本当申し訳ないが、いつかタイミングをみてGitにソースコードをアップロードしようと思う。 そして次は、BitMexで公式が実装したMMBotを使った機械学習を試みてみようと思う。 (BotはここからDLする予定 https://github.com/BitMEX/sample-market-maker) しかし、まだフローを理解していないから、どこに機械学習の要素を入れようか考え中ではある。 また、機械学習の方もいい深層強化学習の方に移行しようかと検討中だ。 Q-Learning ⇒ Q-Network というのも難しくていまいち理解できない・・・。 概要を知るだけならこの辺りがとてもいい感じだったと思う。 http://www.ieice.org/~prmu/jpn/ieice/2018/dt_01_004s.pdf とにもかくにも、深層強化学習の基本コードが書けないと始めらないと思うので、 こちらを優先していくつもりだ。 次回へ続く。
json metadata{"tags":["bitmex","bot","japanese","jp-newbie","dqn"],"links":["https://github.com/BitMEX/sample-market-maker)","http://www.ieice.org/~prmu/jpn/ieice/2018/dt_01_004s.pdf"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitmex
permlinkbitmex-mmbot
titleBitMexのMMBotで機械学習を試みる
Transaction InfoBlock #25838817/Trx 8e38cf6cd9f9fc73165678373f7c0d75b737082b
View Raw JSON Data
{
  "block": 25838817,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "一つ前の投稿したソースだが、何故かすさまじい無駄改行の嵐で、\nとてもじゃないが見れたもんじゃない。\nすぐにでも消したいのにページを開くと強制ログアウトされてしまい編集ができないという謎の減少が起きている。。\n\nということで本当申し訳ないが、いつかタイミングをみてGitにソースコードをアップロードしようと思う。\n\nそして次は、BitMexで公式が実装したMMBotを使った機械学習を試みてみようと思う。\n(BotはここからDLする予定 https://github.com/BitMEX/sample-market-maker)\n\nしかし、まだフローを理解していないから、どこに機械学習の要素を入れようか考え中ではある。\n\nまた、機械学習の方もいい深層強化学習の方に移行しようかと検討中だ。\nQ-Learning ⇒ Q-Network\nというのも難しくていまいち理解できない・・・。\n\n概要を知るだけならこの辺りがとてもいい感じだったと思う。\nhttp://www.ieice.org/~prmu/jpn/ieice/2018/dt_01_004s.pdf\n\nとにもかくにも、深層強化学習の基本コードが書けないと始めらないと思うので、\nこちらを優先していくつもりだ。\n\n次回へ続く。",
      "json_metadata": "{\"tags\":[\"bitmex\",\"bot\",\"japanese\",\"jp-newbie\",\"dqn\"],\"links\":[\"https://github.com/BitMEX/sample-market-maker)\",\"http://www.ieice.org/~prmu/jpn/ieice/2018/dt_01_004s.pdf\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitmex",
      "permlink": "bitmex-mmbot",
      "title": "BitMexのMMBotで機械学習を試みる"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T13:32:51",
  "trx_id": "8e38cf6cd9f9fc73165678373f7c0d75b737082b",
  "trx_in_block": 33,
  "virtual_op": 0
}
2018/09/10 09:40:42
authorsteemitboard
bodyCongratulations @jianty! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) : [![](https://steemitimages.com/70x70/http://steemitboard.com/notifications/firstpayout.png)](http://steemitboard.com/@jianty) You got your First payout <sub>_Click on the badge to view your Board of Honor._</sub> <sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub> **Do not miss the last post from @steemitboard:** <table><tr><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/7CiQEO.png"></a></td><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07">SteemitBoard - Witness Update</a></td></tr><tr><td><a href="https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund"><img src="https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmawPYDAwfrQM8YU6ejD1f87g64cvsmEFn8RQKHJMs4zxg/image.png"></a></td><td><a href="https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund">SteemFest³ - SteemitBoard support the Travel Reimbursement Fund.</a></td></tr></table> > Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authorjianty
parent permlink2kdc6b-bitcoin-fx
permlinksteemitboard-notify-jianty-20180910t094044000z
title
Transaction InfoBlock #25834175/Trx d4ffd15224120db884d9c3691da94ec366044c04
View Raw JSON Data
{
  "block": 25834175,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @jianty! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :\n\n[![](https://steemitimages.com/70x70/http://steemitboard.com/notifications/firstpayout.png)](http://steemitboard.com/@jianty) You got your First payout\n\n<sub>_Click on the badge to view your Board of Honor._</sub>\n<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>\n\n\n\n**Do not miss the last post from @steemitboard:**\n<table><tr><td><a href=\"https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07\"><img src=\"https://steemitimages.com/64x128/http://i.cubeupload.com/7CiQEO.png\"></a></td><td><a href=\"https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2018-09-07\">SteemitBoard - Witness Update</a></td></tr><tr><td><a href=\"https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund\"><img src=\"https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmawPYDAwfrQM8YU6ejD1f87g64cvsmEFn8RQKHJMs4zxg/image.png\"></a></td><td><a href=\"https://steemit.com/steemfest/@steemitboard/steemfest-steemitboard-support-the-travel-reimbursement-fund\">SteemFest³ - SteemitBoard support the Travel Reimbursement Fund.</a></td></tr></table>\n\n> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "jianty",
      "parent_permlink": "2kdc6b-bitcoin-fx",
      "permlink": "steemitboard-notify-jianty-20180910t094044000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-10T09:40:42",
  "trx_id": "d4ffd15224120db884d9c3691da94ec366044c04",
  "trx_in_block": 26,
  "virtual_op": 0
}
jiantyreceived 1.279 STEEM, 1.592 SP author reward for @jianty / bitcoin-fx
2018/09/09 15:28:45
authorjianty
permlinkbitcoin-fx
sbd payout0.000 SBD
steem payout1.279 STEEM
vesting payout2588.741628 VESTS
Transaction InfoBlock #25812337/Virtual Operation #10
View Raw JSON Data
{
  "block": 25812337,
  "op": [
    "author_reward",
    {
      "author": "jianty",
      "permlink": "bitcoin-fx",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "1.279 STEEM",
      "vesting_payout": "2588.741628 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-09T15:28:45",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 10
}
akkkuupvoted (100.00%) @jianty / 2kdc6b-bitcoin-fx
2018/09/08 15:30:30
authorjianty
permlink2kdc6b-bitcoin-fx
voterakkku
weight10000 (100.00%)
Transaction InfoBlock #25783578/Trx cfafa1ae30f49141d63b2372f49e14eea2d74db9
View Raw JSON Data
{
  "block": 25783578,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "akkku",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-08T15:30:30",
  "trx_id": "cfafa1ae30f49141d63b2372f49e14eea2d74db9",
  "trx_in_block": 9,
  "virtual_op": 0
}
tonpaupvoted (10.00%) @jianty / 2kdc6b-bitcoin-fx
2018/09/08 01:37:09
authorjianty
permlink2kdc6b-bitcoin-fx
votertonpa
weight1000 (10.00%)
Transaction InfoBlock #25766916/Trx 3951ef000c39b29cb2941c4781bb11c514215496
View Raw JSON Data
{
  "block": 25766916,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "tonpa",
      "weight": 1000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-08T01:37:09",
  "trx_id": "3951ef000c39b29cb2941c4781bb11c514215496",
  "trx_in_block": 0,
  "virtual_op": 0
}
2018/09/07 20:24:42
authorjianty
permlink2kdc6b-bitcoin-fx
voterkatakoto
weight10000 (100.00%)
Transaction InfoBlock #25760670/Trx 94af64b5ce16b54d0fbc85d3a602f0ce71a4b107
View Raw JSON Data
{
  "block": 25760670,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "katakoto",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T20:24:42",
  "trx_id": "94af64b5ce16b54d0fbc85d3a602f0ce71a4b107",
  "trx_in_block": 1,
  "virtual_op": 0
}
jiantyremoved vote from (0.00%) @jianty / 2kdc6b-bitcoin-fx
2018/09/07 16:25:48
authorjianty
permlink2kdc6b-bitcoin-fx
voterjianty
weight0 (0.00%)
Transaction InfoBlock #25755896/Trx bfc6b5ebd116c23fe7e2a01c1e2635a6c7408814
View Raw JSON Data
{
  "block": 25755896,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "jianty",
      "weight": 0
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T16:25:48",
  "trx_id": "bfc6b5ebd116c23fe7e2a01c1e2635a6c7408814",
  "trx_in_block": 0,
  "virtual_op": 0
}
jiantyupvoted (100.00%) @jianty / 2kdc6b-bitcoin-fx
2018/09/07 16:21:27
authorjianty
permlink2kdc6b-bitcoin-fx
voterjianty
weight10000 (100.00%)
Transaction InfoBlock #25755809/Trx 5c4cf4c37e0df6f6ec7e5a635487bbed2300aac3
View Raw JSON Data
{
  "block": 25755809,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "jianty",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T16:21:27",
  "trx_id": "5c4cf4c37e0df6f6ec7e5a635487bbed2300aac3",
  "trx_in_block": 39,
  "virtual_op": 0
}
2018/09/07 15:57:42
authorjianty
permlink2kdc6b-bitcoin-fx
voteryoungogmarqs
weight2 (0.02%)
Transaction InfoBlock #25755334/Trx 6bb37d52d3b9772ab4dc9fd02fc26c925c4eff91
View Raw JSON Data
{
  "block": 25755334,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "youngogmarqs",
      "weight": 2
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:57:42",
  "trx_id": "6bb37d52d3b9772ab4dc9fd02fc26c925c4eff91",
  "trx_in_block": 39,
  "virtual_op": 0
}
jiantypublished a new post: 2kdc6b-bitcoin-fx
2018/09/07 15:56:21
authorjianty
body<html> <h1>始めに言っておくと、<strong>大損失を生むソースコードですので絶対に使用しないように!</strong></h1> <p><br></p> <p>また、本ソースコードで使用している取引所の売買を実行するメソッドは、Bot実装で有名なUKI氏のブログより参考にさせていただきました。</p> <p>https://note.mu/magimagi1223/n/n5fba7501dcfd</p> <p><br></p> <p>まず仕組みから説明する。</p> <p>強化学習におけるエージェントのアクションはたったの以下2つ。</p> <p>・Long</p> <p>・Short</p> <p>学習モデルはモンテカルロ法で、利確したタイミングで初めてモデル(エージェントの脳みそ)を更新する。</p> <p>そのため、利確するまではいつまでもモデルの更新はない。</p> <p>これだけでもわかる通り、とても学習するのに時間がかかる!</p> <p>流れは以下の通りだ。</p> <p>1.エージェントが買う or 売る</p> <p>2.利確されるまで3.をループ</p> <p>3.以下5つをモデル更新用のメモリに蓄積</p> <p> 「リアルタイムの収益+-」</p> <p> 「ask」</p> <p> 「bid」</p> <p> 「spread」</p> <p> 「 total bid depth ( 売り注文総数) 」</p> <p> 「 total ask depth (買い注文総数) 」</p> <p>4.利確されたらモデルを更新</p> <p><br></p> <p>以下、ソースコードになる。アドバイスがあればお願いしたい。</p> <p>※このコードを使用する際に発生した損失について責任を負いません。このコードはサンプル目的のみを対象としています - 実際の取引にこのコードを使用しないでください。</p> <pre><code>#!/usr/bin/python3<br> <br> # coding: utf-8<br> <br> <br> <br> import datetime<br> <br> import time<br> <br> import os<br> <br> import numpy as np<br> <br> import ccxt<br> <br> import pybitflyer<br> <br> from collections import deque<br> <br> key = 'xxxxxxxxxxxxxxxxxxxxxxx'<br> <br> secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'<br> <br> <br> <br> bitflyer = ccxt.bitflyer({<br> <br> 'apiKey': key,<br> <br> 'secret': secret,<br> <br> })<br> <br> <br> <br> api = pybitflyer.API(key, secret)<br> <br> <br> <br> # 取引する通貨、シンボルを設定<br> <br> COIN = 'BTC'<br> <br> PAIR = 'BTCJPY28SEP2018'<br> <br> <br> <br> # ロット(単位はBTC)<br> <br> LOT = 0.05<br> <br> <br> <br> # 最小注文数(取引所の仕様に応じて設定)<br> <br> AMOUNT_MIN = 0.001<br> <br> <br> <br> # 数量X(この数量よりも下に指値をおく)<br> <br> AMOUNT_THRU = 0.01<br> <br> <br> <br> # 実効Ask/BidからDELTA離れた位置に指値をおく<br> <br> DELTA = 1<br> <br> <br> <br> # レバレッジ設定<br> <br> LEVERAGE = 1.0<br> <br> <br> <br> #------------------------------------------------------------------------------#<br> <br> #log設定<br> <br> import logging<br> <br> logger = logging.getLogger('LoggingTest')<br> <br> logger.setLevel(10)<br> <br> fh = logging.FileHandler('log_mm_bf_' + datetime.datetime.now().strftime('%Y%m%d') + '_' + datetime.datetime.now().strftime('%H%M%S') + '.log')<br> <br> logger.addHandler(fh)<br> <br> sh = logging.StreamHandler()<br> <br> logger.addHandler(sh)<br> <br> formatter = logging.Formatter('%(asctime)s: %(message)s', datefmt="%Y-%m-%d %H:%M:%S")<br> <br> fh.setFormatter(formatter)<br> <br> sh.setFormatter(formatter)<br> <br> <br> <br> #------------------------------------------------------------------------------#<br> <br> # [1]Q関数を離散化して定義する関数 ------------<br> <br> # 観測した状態を離散値にデジタル変換する<br> <br> def bins(clip_min, clip_max, num):<br> <br> &nbsp;&nbsp;&nbsp;return np.linspace(clip_min, clip_max, num + 1)[1:-1]<br> <br> <br> <br> # 各値を離散値に変換<br> <br> def digitize_state(observation):<br> <br> &nbsp;&nbsp;&nbsp;ask, bid, spread, total_ask_depth, total_bid_depth, balance = observation<br> <br> &nbsp;&nbsp;&nbsp;digitized = [<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(ask, bins=bins(0.0, 1.0, num_dizitized)),<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(bid, bins=bins(0.0, 1.0, num_dizitized)),<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(spread, bins=bins(0.0, 1.0, num_dizitized)),<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_ask_depth, bins=bins(0.0, 1.0, num_dizitized)),<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_bid_depth, bins=bins(0.0, 1.0, num_dizitized)),<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(balance, bins=bins(0.0, 1.0, num_dizitized))<br> <br> &nbsp;&nbsp;&nbsp;]<br> <br> &nbsp;&nbsp;&nbsp;return sum([x * (num_dizitized**i) for i, x in enumerate(digitized)])<br> <br> <br> <br> # [2]行動a(t)を求める関数 -------------------------------------<br> <br> def get_action(next_state, episode):<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;#徐々に最適行動のみをとる、ε-greedy法<br> <br> &nbsp;&nbsp;&nbsp;epsilon = 0.5 * (1 / (episode + 1))<br> <br> &nbsp;&nbsp;&nbsp;if epsilon &lt;= np.random.uniform(0, 1):<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.argmax(q_table[next_state])<br> <br> &nbsp;&nbsp;&nbsp;else:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.random.choice([0, 1])<br> <br> &nbsp;&nbsp;&nbsp;return next_action<br> <br> <br> <br> # [3]Qテーブルを更新する(モンテカルロ法) *Qlearningと異なる* -------------------------------------<br> <br> def update_Qtable_montecarlo(q_table, memory):<br> <br> &nbsp;&nbsp;&nbsp;gamma = 0.99<br> <br> &nbsp;&nbsp;&nbsp;alpha = 0.5<br> <br> &nbsp;&nbsp;&nbsp;total_reward_t = 0<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while (memory.len() &gt; 0):<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(state, action, reward) = memory.sample()<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = gamma * total_reward_t &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 時間割引率をかける<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Q関数を更新<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table[state, action] = q_table[state, action] + alpha*(reward+total_reward_t-q_table[state, action])<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = total_reward_t + reward &nbsp;&nbsp;&nbsp;# ステップtより先でもらえた報酬の合計を更新<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;return q_table<br> <br> <br> <br> # [4]1試行の各ステップの行動を保存しておくメモリクラス<br> <br> class Memory:<br> <br> &nbsp;&nbsp;&nbsp;def __init__(self, max_size=400):<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer = deque(maxlen=max_size)<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;def add(self, experience):<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer.append(experience)<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;def sample(self):<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self.buffer.pop() &nbsp;# 最後尾のメモリを取り出す<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;def len(self):<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return len(self.buffer)<br> <br> <br> <br> # エージェント パラメータ設定--------------------------------------------------------<br> <br> <br> <br> # バッファーメモリの大きさ<br> <br> memory = Memory(max_size=400)<br> <br> num_dizitized = 10<br> <br> <br> <br> # 前回のテーブルが存在すれば読み込み(状態を6分割^(5変数)にデジタル変換してQ関数(表)を作成)<br> <br> if os.path.exists('q_table.csv'):<br> <br> &nbsp;&nbsp;&nbsp;q_table = np.loadtxt('q_table.csv', dtype=float, delimiter=',')<br> <br> &nbsp;&nbsp;&nbsp;print("parameter loaded.")<br> <br> else:<br> <br> &nbsp;&nbsp;&nbsp;q_table = np.random.uniform(low=0.0, high=1.0, size=(num_dizitized**6, 2))<br> <br> <br> <br> <br> <br> # JPY残高を参照する関数 -------------------------------------<br> <br> def get_asset():<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetch_balance()<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br> <br> &nbsp;&nbsp;&nbsp;return value<br> <br> <br> <br> # JPY証拠金を参照する関数 -------------------------------------<br> <br> def get_colla():<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.privateGetGetcollateral()<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br> <br> &nbsp;&nbsp;&nbsp;return value<br> <br> <br> <br> # JPY証拠金変動履歴を参照する関数 -------------------------------------<br> <br> def get_collateralhistory():<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = api.getcollateralhistory(product_code=PAIR, count=1)[0]<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br> <br> &nbsp;&nbsp;&nbsp;return value<br> <br> <br> <br> # 板情報から実効Ask/Bid(=指値を入れる基準値)を計算する関数 -------------------------------------<br> <br> def get_effective_tick(size_thru, rate_ask, size_ask, rate_bid, size_bid):<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetchOrderBook(PAIR)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;i = 0<br> <br> &nbsp;&nbsp;&nbsp;s = 0<br> <br> &nbsp;&nbsp;&nbsp;while s &lt;= size_thru:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['bids'][i][0] == rate_bid:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1] - size_bid<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1]<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i += 1<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;j = 0<br> <br> &nbsp;&nbsp;&nbsp;t = 0<br> <br> &nbsp;&nbsp;&nbsp;while t &lt;= size_thru:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['asks'][j][0] == rate_ask:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1] - size_ask<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1]<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j += 1<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br> <br> &nbsp;&nbsp;&nbsp;return {'bid': value['bids'][i-1][0], 'ask': value['asks'][j-1][0]}<br> <br> <br> <br> # 自分のポジションを取得する関数 -------------------------------------<br> <br> def getposition():<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ポジション - 確認')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getpositions( params = { "product_code" : PAIR })<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br> <br> &nbsp;&nbsp;&nbsp;return value<br> <br> <br> <br> # 成行注文する関数 -------------------------------------<br> <br> def market(side, size):<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('成行注文 - 実行')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'market', side = side, amount = size)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br> <br> &nbsp;&nbsp;&nbsp;return value<br> <br> <br> <br> # 指値注文する関数 -------------------------------------<br> <br> def limit(side, size, price):<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('指値注文 - 実行')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'limit', side = side, amount = size, price = price)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1.5)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br> <br> &nbsp;&nbsp;&nbsp;return value<br> <br> <br> <br> # 注文をキャンセルする関数 -------------------------------------<br> <br> def cancel(id):<br> <br> &nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('キャンセル - 実行')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.cancelOrder(symbol = PAIR, id = id)<br> <br> &nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 指値が約定していた(=キャンセルが通らなかった)場合、<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 注文情報を更新(約定済み)して返す<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = get_status(id)<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br> <br> &nbsp;&nbsp;&nbsp;return value<br> <br> <br> <br> # 指定した注文idのステータスを参照する関数 -------------------------------------<br> <br> def get_status(id):<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;err_cnt = 0<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;if PAIR == 'BTC/JPY':<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = 'BTC_JPY'<br> <br> &nbsp;&nbsp;&nbsp;else:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = PAIR<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getchildorders(params = {'product_code': PRODUCT, 'child_order_acceptance_id': id})[0]<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ステータスが受け取れない為61秒待機。')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(61)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt += 1<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if err_cnt == 5:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt = 0<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {'id' : 'null'}<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;# APIで受け取った値を読み換える<br> <br> &nbsp;&nbsp;&nbsp;if value['child_order_state'] == 'ACTIVE':<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'open'<br> <br> &nbsp;&nbsp;&nbsp;elif value['child_order_state'] == 'COMPLETED':<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'closed'<br> <br> &nbsp;&nbsp;&nbsp;else:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = value['child_order_state']<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;# 未約定量を計算する<br> <br> &nbsp;&nbsp;&nbsp;remaining = float(value['size']) - float(value['executed_size'])<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.1)<br> <br> &nbsp;&nbsp;&nbsp;return {'id': value['child_order_acceptance_id'], 'status': status, 'filled': value['executed_size'], 'remaining': remaining, 'amount': value['size'], 'price': value['price']}<br> <br> <br> <br> #------------------------------------------------------------------------------#<br> <br> <br> <br> # 未約定量が存在することを示すフラグ<br> <br> remaining_ask_flag = 0<br> <br> remaining_bid_flag = 0<br> <br> <br> <br> #------------------------------------------------------------------------------#<br> <br> <br> <br> logger.info('--------TradeStart--------')<br> <br> logger.info('BOT TYPE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: MarketMaker @ bitFlyer')<br> <br> logger.info('SYMBOL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(PAIR))<br> <br> logger.info('LOT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0} {1}'.format(LOT, COIN))<br> <br> <br> <br> # 残高取得<br> <br> TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br> <br> logger.info('--------------------------')<br> <br> logger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(TOTAL))<br> <br> <br> <br> # 現在の状態tを取得<br> <br> tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br> <br> ask = float(tick['ask'])<br> <br> bid = float(tick['bid'])<br> <br> spread = (ask - bid) / bid<br> <br> <br> <br> result = bitflyer.fetch_ticker(symbol=PAIR)<br> <br> total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br> <br> observation = ask, bid, spread, total_ask_depth, total_bid_depth, TOTAL<br> <br> state = digitize_state(observation)<br> <br> <br> <br> prev_change = get_collateralhistory()['change']<br> <br> trade_bid = {}<br> <br> trade_ask = {}<br> <br> trades = []<br> <br> action = np.argmax(q_table[state])<br> <br> before_position = float(get_colla()['open_position_pnl'])<br> <br> episode = 0<br> <br> total_episode = 0<br> <br> reward = 0.0<br> <br> episode_reward = 0<br> <br> EARNING = 0<br> <br> contract = 'false'<br> <br> <br> <br> long_cnt = 0<br> <br> short_cnt = 0<br> <br> <br> <br> # 利確設定 <br> <br> CONTRACT_PRICE = 100<br> <br> <br> <br> # 損切設定 <br> <br> FAILURE_PRICE = -100<br> <br> <br> <br> position_flag = 0<br> <br> #------------------------------- メインループ -------------------------------------#<br> <br> while True:<br> <br> <br> <br> #------------------------------- エージェントアクション -------------------------------------#<br> <br> &nbsp;&nbsp;&nbsp;# 買い<br> <br> &nbsp;&nbsp;&nbsp;if action == 0:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 0<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------long-----')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_bid = market('buy', LOT)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_bid)<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;# 売り<br> <br> &nbsp;&nbsp;&nbsp;if action == 1:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 1<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------short-----')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_ask = market('sell', LOT)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_ask)<br> <br> <br> <br> #------------------------------- 報酬 -------------------------------------#<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;logger.info('------経過観察中-----')<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 実行後の評価損益を記録<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;after_TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------エージェントの設定値--------')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('実行回数 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(episode))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ACTION &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(action))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------リアルタイム残高--------')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(after_TOTAL))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (利確)報酬を記録<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change = get_collateralhistory()['change']<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(prev_change))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(change))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if change != prev_change:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev_change = change<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = change<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (含益)報酬を記録<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(before_position))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(get_colla()['open_position_pnl']))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if before_position != float(get_colla()['open_position_pnl']):<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = float(reward) + float(get_colla()['open_position_pnl'])<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_position = float(get_colla()['open_position_pnl'])<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 総合利益パーセント算出<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOTAL_PERCENT = float(after_TOTAL/TOTAL) * 100.0<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 収益<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EARNING = after_TOTAL - TOTAL<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode_reward = float(episode_reward) + reward<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------評価--------')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('REWARD &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(float(reward)))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL REWARD &nbsp;&nbsp;: {0}'.format(float(episode_reward)))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('EARNING &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {:+f}'.format(float(EARNING)))<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL PERCENT &nbsp;: {0} %'.format(TOTAL_PERCENT))<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 利益+2%または損失-2%に到達したら利確<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if FAILURE_PRICE &gt;= EARNING or EARNING &gt;= CONTRACT_PRICE:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for trade in trades:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 'null' != trade['id']:<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 0:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('sell', LOT)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 1:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('buy', LOT)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------約定完了-----')<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 現在の状態tを取得<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ask = float(tick['ask'])<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bid = float(tick['bid'])<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spread = (ask - bid) / bid<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = bitflyer.fetch_ticker(symbol=PAIR)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observation = ask, bid, spread, total_ask_depth, total_bid_depth, after_TOTAL<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = digitize_state(observation)<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# メモリに、現在の状態と行った行動、得た報酬を記録する<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memory.add((state, action, reward))<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 約定されたタイミングでテーブル更新<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if contract == 'true':<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('約定確定')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table = update_Qtable_montecarlo(q_table, memory)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = np.argmax(q_table[state])<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = np.array(q_table)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.savetxt("q_table.csv", data, delimiter=',')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'false'<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> <br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 次ステップへ行動と状態を更新<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_state = digitize_state(observation) &nbsp;# t+1での観測状態を、離散値に変換<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = get_action(next_state, episode) &nbsp;# 次の行動a_{t+1}を求める<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = next_action &nbsp;# a_{t+1}<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = next_state &nbsp;# s_{t+1}<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# エピソード記録<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode += 1<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_episode += 1<br> <br> &nbsp;&nbsp;&nbsp;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 報酬リセット<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = 0<br> <br> <br> <br> <br> <br> <br> <br> </code></pre> </html>
json metadata{"tags":["bitcoin","fx","bot","japanese","jp-newbie"],"links":["https://note.mu/magimagi1223/n/n5fba7501dcfd"],"app":"steemit/0.1","format":"html"}
parent author
parent permlinkbitcoin
permlink2kdc6b-bitcoin-fx
title強化学習によるBitcoin FXの攻略 ソースコード公開
Transaction InfoBlock #25755307/Trx a84891136bdd9b37145b59a9890eed843d67b1cd
View Raw JSON Data
{
  "block": 25755307,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "<html>\n<h1>始めに言っておくと、<strong>大損失を生むソースコードですので絶対に使用しないように!</strong></h1>\n<p><br></p>\n<p>また、本ソースコードで使用している取引所の売買を実行するメソッドは、Bot実装で有名なUKI氏のブログより参考にさせていただきました。</p>\n<p>https://note.mu/magimagi1223/n/n5fba7501dcfd</p>\n<p><br></p>\n<p>まず仕組みから説明する。</p>\n<p>強化学習におけるエージェントのアクションはたったの以下2つ。</p>\n<p>・Long</p>\n<p>・Short</p>\n<p>学習モデルはモンテカルロ法で、利確したタイミングで初めてモデル(エージェントの脳みそ)を更新する。</p>\n<p>そのため、利確するまではいつまでもモデルの更新はない。</p>\n<p>これだけでもわかる通り、とても学習するのに時間がかかる!</p>\n<p>流れは以下の通りだ。</p>\n<p>1.エージェントが買う or 売る</p>\n<p>2.利確されるまで3.をループ</p>\n<p>3.以下5つをモデル更新用のメモリに蓄積</p>\n<p> 「リアルタイムの収益+-」</p>\n<p> 「ask」</p>\n<p> 「bid」</p>\n<p> 「spread」</p>\n<p> 「 total bid depth ( 売り注文総数) 」</p>\n<p> 「 total ask depth (買い注文総数) 」</p>\n<p>4.利確されたらモデルを更新</p>\n<p><br></p>\n<p>以下、ソースコードになる。アドバイスがあればお願いしたい。</p>\n<p>※このコードを使用する際に発生した損失について責任を負いません。このコードはサンプル目的のみを対象としています - 実際の取引にこのコードを使用しないでください。</p>\n<pre><code>#!/usr/bin/python3<br>\n<br>\n# coding: utf-8<br>\n<br>\n<br>\n<br>\nimport datetime<br>\n<br>\nimport time<br>\n<br>\nimport os<br>\n<br>\nimport numpy as np<br>\n<br>\nimport ccxt<br>\n<br>\nimport pybitflyer<br>\n<br>\nfrom collections import deque<br>\n<br>\nkey = 'xxxxxxxxxxxxxxxxxxxxxxx'<br>\n<br>\nsecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'<br>\n<br>\n<br>\n<br>\nbitflyer = ccxt.bitflyer({<br>\n<br>\n'apiKey': key,<br>\n<br>\n'secret': secret,<br>\n<br>\n})<br>\n<br>\n<br>\n<br>\napi = pybitflyer.API(key, secret)<br>\n<br>\n<br>\n<br>\n# 取引する通貨、シンボルを設定<br>\n<br>\nCOIN = 'BTC'<br>\n<br>\nPAIR = 'BTCJPY28SEP2018'<br>\n<br>\n<br>\n<br>\n# ロット(単位はBTC)<br>\n<br>\nLOT = 0.05<br>\n<br>\n<br>\n<br>\n# 最小注文数(取引所の仕様に応じて設定)<br>\n<br>\nAMOUNT_MIN = 0.001<br>\n<br>\n<br>\n<br>\n# 数量X(この数量よりも下に指値をおく)<br>\n<br>\nAMOUNT_THRU = 0.01<br>\n<br>\n<br>\n<br>\n# 実効Ask/BidからDELTA離れた位置に指値をおく<br>\n<br>\nDELTA = 1<br>\n<br>\n<br>\n<br>\n# レバレッジ設定<br>\n<br>\nLEVERAGE = 1.0<br>\n<br>\n<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n<br>\n#log設定<br>\n<br>\nimport logging<br>\n<br>\nlogger = logging.getLogger('LoggingTest')<br>\n<br>\nlogger.setLevel(10)<br>\n<br>\nfh = logging.FileHandler('log_mm_bf_' + datetime.datetime.now().strftime('%Y%m%d') + '_' + datetime.datetime.now().strftime('%H%M%S') + '.log')<br>\n<br>\nlogger.addHandler(fh)<br>\n<br>\nsh = logging.StreamHandler()<br>\n<br>\nlogger.addHandler(sh)<br>\n<br>\nformatter = logging.Formatter('%(asctime)s: %(message)s', datefmt=\"%Y-%m-%d %H:%M:%S\")<br>\n<br>\nfh.setFormatter(formatter)<br>\n<br>\nsh.setFormatter(formatter)<br>\n<br>\n<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n<br>\n# [1]Q関数を離散化して定義する関数 ------------<br>\n<br>\n# 観測した状態を離散値にデジタル変換する<br>\n<br>\ndef bins(clip_min, clip_max, num):<br>\n<br>\n &nbsp;&nbsp;&nbsp;return np.linspace(clip_min, clip_max, num + 1)[1:-1]<br>\n<br>\n<br>\n<br>\n# 各値を離散値に変換<br>\n<br>\ndef digitize_state(observation):<br>\n<br>\n &nbsp;&nbsp;&nbsp;ask, bid, spread, total_ask_depth, total_bid_depth, balance = observation<br>\n<br>\n &nbsp;&nbsp;&nbsp;digitized = [<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(ask, bins=bins(0.0, 1.0, num_dizitized)),<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(bid, bins=bins(0.0, 1.0, num_dizitized)),<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(spread, bins=bins(0.0, 1.0, num_dizitized)),<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_ask_depth, bins=bins(0.0, 1.0, num_dizitized)),<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_bid_depth, bins=bins(0.0, 1.0, num_dizitized)),<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(balance, bins=bins(0.0, 1.0, num_dizitized))<br>\n<br>\n &nbsp;&nbsp;&nbsp;]<br>\n<br>\n &nbsp;&nbsp;&nbsp;return sum([x * (num_dizitized**i) for i, x in enumerate(digitized)])<br>\n<br>\n<br>\n<br>\n# [2]行動a(t)を求める関数 -------------------------------------<br>\n<br>\ndef get_action(next_state, episode):<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;#徐々に最適行動のみをとる、ε-greedy法<br>\n<br>\n &nbsp;&nbsp;&nbsp;epsilon = 0.5 * (1 / (episode + 1))<br>\n<br>\n &nbsp;&nbsp;&nbsp;if epsilon &lt;= np.random.uniform(0, 1):<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.argmax(q_table[next_state])<br>\n<br>\n &nbsp;&nbsp;&nbsp;else:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.random.choice([0, 1])<br>\n<br>\n &nbsp;&nbsp;&nbsp;return next_action<br>\n<br>\n<br>\n<br>\n# [3]Qテーブルを更新する(モンテカルロ法) *Qlearningと異なる* -------------------------------------<br>\n<br>\ndef update_Qtable_montecarlo(q_table, memory):<br>\n<br>\n &nbsp;&nbsp;&nbsp;gamma = 0.99<br>\n<br>\n &nbsp;&nbsp;&nbsp;alpha = 0.5<br>\n<br>\n &nbsp;&nbsp;&nbsp;total_reward_t = 0<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while (memory.len() &gt; 0):<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(state, action, reward) = memory.sample()<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = gamma * total_reward_t &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 時間割引率をかける<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Q関数を更新<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table[state, action] = q_table[state, action] + alpha*(reward+total_reward_t-q_table[state, action])<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = total_reward_t + reward &nbsp;&nbsp;&nbsp;# ステップtより先でもらえた報酬の合計を更新<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;return q_table<br>\n<br>\n<br>\n<br>\n# [4]1試行の各ステップの行動を保存しておくメモリクラス<br>\n<br>\nclass Memory:<br>\n<br>\n &nbsp;&nbsp;&nbsp;def __init__(self, max_size=400):<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer = deque(maxlen=max_size)<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;def add(self, experience):<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer.append(experience)<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;def sample(self):<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self.buffer.pop() &nbsp;# 最後尾のメモリを取り出す<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;def len(self):<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return len(self.buffer)<br>\n<br>\n<br>\n<br>\n# エージェント パラメータ設定--------------------------------------------------------<br>\n<br>\n<br>\n<br>\n# バッファーメモリの大きさ<br>\n<br>\nmemory = Memory(max_size=400)<br>\n<br>\nnum_dizitized = 10<br>\n<br>\n<br>\n<br>\n# 前回のテーブルが存在すれば読み込み(状態を6分割^(5変数)にデジタル変換してQ関数(表)を作成)<br>\n<br>\nif os.path.exists('q_table.csv'):<br>\n<br>\n &nbsp;&nbsp;&nbsp;q_table = np.loadtxt('q_table.csv', dtype=float, delimiter=',')<br>\n<br>\n &nbsp;&nbsp;&nbsp;print(\"parameter loaded.\")<br>\n<br>\nelse:<br>\n<br>\n &nbsp;&nbsp;&nbsp;q_table = np.random.uniform(low=0.0, high=1.0, size=(num_dizitized**6, 2))<br>\n<br>\n<br>\n<br>\n<br>\n<br>\n# JPY残高を参照する関数 -------------------------------------<br>\n<br>\ndef get_asset():<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetch_balance()<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n<br>\n<br>\n# JPY証拠金を参照する関数 -------------------------------------<br>\n<br>\ndef get_colla():<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.privateGetGetcollateral()<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n<br>\n<br>\n# JPY証拠金変動履歴を参照する関数 -------------------------------------<br>\n<br>\ndef get_collateralhistory():<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = api.getcollateralhistory(product_code=PAIR, count=1)[0]<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n<br>\n<br>\n# 板情報から実効Ask/Bid(=指値を入れる基準値)を計算する関数 -------------------------------------<br>\n<br>\ndef get_effective_tick(size_thru, rate_ask, size_ask, rate_bid, size_bid):<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetchOrderBook(PAIR)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;i = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;s = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;while s &lt;= size_thru:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['bids'][i][0] == rate_bid:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1] - size_bid<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1]<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i += 1<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;j = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;t = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;while t &lt;= size_thru:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['asks'][j][0] == rate_ask:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1] - size_ask<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1]<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j += 1<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return {'bid': value['bids'][i-1][0], 'ask': value['asks'][j-1][0]}<br>\n<br>\n<br>\n<br>\n# 自分のポジションを取得する関数 -------------------------------------<br>\n<br>\ndef getposition():<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ポジション - 確認')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getpositions( params = { \"product_code\" : PAIR })<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n<br>\n<br>\n# 成行注文する関数 -------------------------------------<br>\n<br>\ndef market(side, size):<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('成行注文 - 実行')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'market', side = side, amount = size)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n<br>\n<br>\n# 指値注文する関数 -------------------------------------<br>\n<br>\ndef limit(side, size, price):<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('指値注文 - 実行')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'limit', side = side, amount = size, price = price)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1.5)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n<br>\n<br>\n# 注文をキャンセルする関数 -------------------------------------<br>\n<br>\ndef cancel(id):<br>\n<br>\n &nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('キャンセル - 実行')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.cancelOrder(symbol = PAIR, id = id)<br>\n<br>\n &nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 指値が約定していた(=キャンセルが通らなかった)場合、<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 注文情報を更新(約定済み)して返す<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = get_status(id)<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n<br>\n<br>\n# 指定した注文idのステータスを参照する関数 -------------------------------------<br>\n<br>\ndef get_status(id):<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;err_cnt = 0<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;if PAIR == 'BTC/JPY':<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = 'BTC_JPY'<br>\n<br>\n &nbsp;&nbsp;&nbsp;else:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = PAIR<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getchildorders(params = {'product_code': PRODUCT, 'child_order_acceptance_id': id})[0]<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ステータスが受け取れない為61秒待機。')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(61)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt += 1<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if err_cnt == 5:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {'id' : 'null'}<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;# APIで受け取った値を読み換える<br>\n<br>\n &nbsp;&nbsp;&nbsp;if value['child_order_state'] == 'ACTIVE':<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'open'<br>\n<br>\n &nbsp;&nbsp;&nbsp;elif value['child_order_state'] == 'COMPLETED':<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'closed'<br>\n<br>\n &nbsp;&nbsp;&nbsp;else:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = value['child_order_state']<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;# 未約定量を計算する<br>\n<br>\n &nbsp;&nbsp;&nbsp;remaining = float(value['size']) - float(value['executed_size'])<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.1)<br>\n<br>\n &nbsp;&nbsp;&nbsp;return {'id': value['child_order_acceptance_id'], 'status': status, 'filled': value['executed_size'], 'remaining': remaining, 'amount': value['size'], 'price': value['price']}<br>\n<br>\n<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n<br>\n<br>\n<br>\n# 未約定量が存在することを示すフラグ<br>\n<br>\nremaining_ask_flag = 0<br>\n<br>\nremaining_bid_flag = 0<br>\n<br>\n<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n<br>\n<br>\n<br>\nlogger.info('--------TradeStart--------')<br>\n<br>\nlogger.info('BOT TYPE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: MarketMaker @ bitFlyer')<br>\n<br>\nlogger.info('SYMBOL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(PAIR))<br>\n<br>\nlogger.info('LOT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0} {1}'.format(LOT, COIN))<br>\n<br>\n<br>\n<br>\n# 残高取得<br>\n<br>\nTOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br>\n<br>\nlogger.info('--------------------------')<br>\n<br>\nlogger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(TOTAL))<br>\n<br>\n<br>\n<br>\n# 現在の状態tを取得<br>\n<br>\ntick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br>\n<br>\nask = float(tick['ask'])<br>\n<br>\nbid = float(tick['bid'])<br>\n<br>\nspread = (ask - bid) / bid<br>\n<br>\n<br>\n<br>\nresult = bitflyer.fetch_ticker(symbol=PAIR)<br>\n<br>\ntotal_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br>\n<br>\nobservation = ask, bid, spread, total_ask_depth, total_bid_depth, TOTAL<br>\n<br>\nstate = digitize_state(observation)<br>\n<br>\n<br>\n<br>\nprev_change = get_collateralhistory()['change']<br>\n<br>\ntrade_bid = {}<br>\n<br>\ntrade_ask = {}<br>\n<br>\ntrades = []<br>\n<br>\naction = np.argmax(q_table[state])<br>\n<br>\nbefore_position = float(get_colla()['open_position_pnl'])<br>\n<br>\nepisode = 0<br>\n<br>\ntotal_episode = 0<br>\n<br>\nreward = 0.0<br>\n<br>\nepisode_reward = 0<br>\n<br>\nEARNING = 0<br>\n<br>\ncontract = 'false'<br>\n<br>\n<br>\n<br>\nlong_cnt = 0<br>\n<br>\nshort_cnt = 0<br>\n<br>\n<br>\n<br>\n# 利確設定 <br>\n<br>\nCONTRACT_PRICE = 100<br>\n<br>\n<br>\n<br>\n# 損切設定 <br>\n<br>\nFAILURE_PRICE = -100<br>\n<br>\n<br>\n<br>\nposition_flag = 0<br>\n<br>\n#------------------------------- メインループ -------------------------------------#<br>\n<br>\nwhile True:<br>\n<br>\n<br>\n<br>\n#------------------------------- エージェントアクション -------------------------------------#<br>\n<br>\n &nbsp;&nbsp;&nbsp;# 買い<br>\n<br>\n &nbsp;&nbsp;&nbsp;if action == 0:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------long-----')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_bid = market('buy', LOT)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_bid)<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;# 売り<br>\n<br>\n &nbsp;&nbsp;&nbsp;if action == 1:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 1<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------short-----')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_ask = market('sell', LOT)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_ask)<br>\n<br>\n<br>\n<br>\n#------------------------------- 報酬 -------------------------------------#<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;logger.info('------経過観察中-----')<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 実行後の評価損益を記録<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;after_TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------エージェントの設定値--------')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('実行回数 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(episode))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ACTION &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(action))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------リアルタイム残高--------')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(after_TOTAL))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (利確)報酬を記録<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change = get_collateralhistory()['change']<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(prev_change))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(change))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if change != prev_change:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev_change = change<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = change<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (含益)報酬を記録<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(before_position))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(get_colla()['open_position_pnl']))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if before_position != float(get_colla()['open_position_pnl']):<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = float(reward) + float(get_colla()['open_position_pnl'])<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_position = float(get_colla()['open_position_pnl'])<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 総合利益パーセント算出<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOTAL_PERCENT = float(after_TOTAL/TOTAL) * 100.0<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 収益<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EARNING = after_TOTAL - TOTAL<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode_reward = float(episode_reward) + reward<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------評価--------')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('REWARD &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(float(reward)))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL REWARD &nbsp;&nbsp;: {0}'.format(float(episode_reward)))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('EARNING &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {:+f}'.format(float(EARNING)))<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL PERCENT &nbsp;: {0} %'.format(TOTAL_PERCENT))<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 利益+2%または損失-2%に到達したら利確<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if FAILURE_PRICE &gt;= EARNING or EARNING &gt;= CONTRACT_PRICE:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for trade in trades:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 'null' != trade['id']:<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 0:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('sell', LOT)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 1:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('buy', LOT)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------約定完了-----')<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 現在の状態tを取得<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ask = float(tick['ask'])<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bid = float(tick['bid'])<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spread = (ask - bid) / bid<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = bitflyer.fetch_ticker(symbol=PAIR)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observation = ask, bid, spread, total_ask_depth, total_bid_depth, after_TOTAL<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = digitize_state(observation)<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# メモリに、現在の状態と行った行動、得た報酬を記録する<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memory.add((state, action, reward))<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 約定されたタイミングでテーブル更新<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if contract == 'true':<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('約定確定')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table = update_Qtable_montecarlo(q_table, memory)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = np.argmax(q_table[state])<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = np.array(q_table)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.savetxt(\"q_table.csv\", data, delimiter=',')<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'false'<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 次ステップへ行動と状態を更新<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_state = digitize_state(observation) &nbsp;# t+1での観測状態を、離散値に変換<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = get_action(next_state, episode) &nbsp;# 次の行動a_{t+1}を求める<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = next_action &nbsp;# a_{t+1}<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = next_state &nbsp;# s_{t+1}<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# エピソード記録<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode += 1<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_episode += 1<br>\n<br>\n &nbsp;&nbsp;&nbsp;<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 報酬リセット<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = 0<br>\n<br>\n<br>\n<br>\n<br>\n<br>\n<br>\n<br>\n</code></pre>\n</html>",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"fx\",\"bot\",\"japanese\",\"jp-newbie\"],\"links\":[\"https://note.mu/magimagi1223/n/n5fba7501dcfd\"],\"app\":\"steemit/0.1\",\"format\":\"html\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "2kdc6b-bitcoin-fx",
      "title": "強化学習によるBitcoin FXの攻略 ソースコード公開"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:56:21",
  "trx_id": "a84891136bdd9b37145b59a9890eed843d67b1cd",
  "trx_in_block": 1,
  "virtual_op": 0
}
2018/09/07 15:55:48
authorjianty
permlink2kdc6b-bitcoin-fx
voterxanoxt
weight500 (5.00%)
Transaction InfoBlock #25755296/Trx 86063570cfa0671584fe4407fefeeb6b29ea426e
View Raw JSON Data
{
  "block": 25755296,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "xanoxt",
      "weight": 500
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:55:48",
  "trx_id": "86063570cfa0671584fe4407fefeeb6b29ea426e",
  "trx_in_block": 30,
  "virtual_op": 0
}
2018/09/07 15:55:42
authorjianty
permlink2kdc6b-bitcoin-fx
votersumomo
weight750 (7.50%)
Transaction InfoBlock #25755294/Trx 1cff27b7776418d7e6ed87bcd70cbae0d8173d1e
View Raw JSON Data
{
  "block": 25755294,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "sumomo",
      "weight": 750
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:55:42",
  "trx_id": "1cff27b7776418d7e6ed87bcd70cbae0d8173d1e",
  "trx_in_block": 11,
  "virtual_op": 0
}
2018/09/07 15:55:39
authorjianty
permlink2kdc6b-bitcoin-fx
votersteemit-jp
weight1500 (15.00%)
Transaction InfoBlock #25755293/Trx e8a7618194813b5d4a22736ea883df1f48998dea
View Raw JSON Data
{
  "block": 25755293,
  "op": [
    "vote",
    {
      "author": "jianty",
      "permlink": "2kdc6b-bitcoin-fx",
      "voter": "steemit-jp",
      "weight": 1500
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:55:39",
  "trx_id": "e8a7618194813b5d4a22736ea883df1f48998dea",
  "trx_in_block": 3,
  "virtual_op": 0
}
jiantypublished a new post: 2kdc6b-bitcoin-fx
2018/09/07 15:55:33
authorjianty
body<html> <h1>始めに言っておくと、<strong>大損害を生むソースコードですので絶対に使用しないように!</strong></h1> <p><br></p> <p>また、本ソースコードで使用している取引所の売買を実行するメソッドは、Bot実装で有名なUKI氏のブログより参考にさせていただきました。</p> <p>https://note.mu/magimagi1223/n/n5fba7501dcfd</p> <p><br></p> <p>まず仕組みから説明する。</p> <p>強化学習におけるエージェントのアクションはたったの以下2つ。</p> <p>・Long</p> <p>・Short</p> <p>学習モデルはモンテカルロ法で、利確したタイミングで初めてモデル(エージェントの脳みそ)を更新する。</p> <p>そのため、利確するまではいつまでもモデルの更新はない。</p> <p>これだけでもわかる通り、とても学習するのに時間がかかる!</p> <p>流れは以下の通りだ。</p> <p>1.エージェントが買う or 売る</p> <p>2.利確されるまで3.をループ</p> <p>3.以下5つをモデル更新用のメモリに蓄積</p> <p> 「リアルタイムの収益+-」</p> <p> 「ask」</p> <p> 「bid」</p> <p> 「spread」</p> <p> 「 total bid depth ( 売り注文総数) 」</p> <p> 「 total ask depth (買い注文総数) 」</p> <p>4.利確されたらモデルを更新</p> <p><br></p> <p>以下、ソースコードになる。アドバイスがあればお願いしたい。</p> <p>※このコードを使用する際に発生した損失について責任を負いません。このコードはサンプル目的のみを対象としています - 実際の取引にこのコードを使用しないでください。</p> <pre><code>#!/usr/bin/python3<br> # coding: utf-8<br> <br> import datetime<br> import time<br> import os<br> import numpy as np<br> import ccxt<br> import pybitflyer<br> from collections import deque<br> key = 'xxxxxxxxxxxxxxxxxxxxxxx'<br> secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'<br> <br> bitflyer = ccxt.bitflyer({<br> 'apiKey': key,<br> 'secret': secret,<br> })<br> <br> api = pybitflyer.API(key, secret)<br> <br> # 取引する通貨、シンボルを設定<br> COIN = 'BTC'<br> PAIR = 'BTCJPY28SEP2018'<br> <br> # ロット(単位はBTC)<br> LOT = 0.05<br> <br> # 最小注文数(取引所の仕様に応じて設定)<br> AMOUNT_MIN = 0.001<br> <br> # 数量X(この数量よりも下に指値をおく)<br> AMOUNT_THRU = 0.01<br> <br> # 実効Ask/BidからDELTA離れた位置に指値をおく<br> DELTA = 1<br> <br> # レバレッジ設定<br> LEVERAGE = 1.0<br> <br> #------------------------------------------------------------------------------#<br> #log設定<br> import logging<br> logger = logging.getLogger('LoggingTest')<br> logger.setLevel(10)<br> fh = logging.FileHandler('log_mm_bf_' + datetime.datetime.now().strftime('%Y%m%d') + '_' + datetime.datetime.now().strftime('%H%M%S') + '.log')<br> logger.addHandler(fh)<br> sh = logging.StreamHandler()<br> logger.addHandler(sh)<br> formatter = logging.Formatter('%(asctime)s: %(message)s', datefmt="%Y-%m-%d %H:%M:%S")<br> fh.setFormatter(formatter)<br> sh.setFormatter(formatter)<br> <br> #------------------------------------------------------------------------------#<br> # [1]Q関数を離散化して定義する関数 ------------<br> # 観測した状態を離散値にデジタル変換する<br> def bins(clip_min, clip_max, num):<br> &nbsp;&nbsp;&nbsp;return np.linspace(clip_min, clip_max, num + 1)[1:-1]<br> <br> # 各値を離散値に変換<br> def digitize_state(observation):<br> &nbsp;&nbsp;&nbsp;ask, bid, spread, total_ask_depth, total_bid_depth, balance = observation<br> &nbsp;&nbsp;&nbsp;digitized = [<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(ask, bins=bins(0.0, 1.0, num_dizitized)),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(bid, bins=bins(0.0, 1.0, num_dizitized)),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(spread, bins=bins(0.0, 1.0, num_dizitized)),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_ask_depth, bins=bins(0.0, 1.0, num_dizitized)),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_bid_depth, bins=bins(0.0, 1.0, num_dizitized)),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(balance, bins=bins(0.0, 1.0, num_dizitized))<br> &nbsp;&nbsp;&nbsp;]<br> &nbsp;&nbsp;&nbsp;return sum([x * (num_dizitized**i) for i, x in enumerate(digitized)])<br> <br> # [2]行動a(t)を求める関数 -------------------------------------<br> def get_action(next_state, episode):<br> <br> &nbsp;&nbsp;&nbsp;#徐々に最適行動のみをとる、ε-greedy法<br> &nbsp;&nbsp;&nbsp;epsilon = 0.5 * (1 / (episode + 1))<br> &nbsp;&nbsp;&nbsp;if epsilon &lt;= np.random.uniform(0, 1):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.argmax(q_table[next_state])<br> &nbsp;&nbsp;&nbsp;else:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.random.choice([0, 1])<br> &nbsp;&nbsp;&nbsp;return next_action<br> <br> # [3]Qテーブルを更新する(モンテカルロ法) *Qlearningと異なる* -------------------------------------<br> def update_Qtable_montecarlo(q_table, memory):<br> &nbsp;&nbsp;&nbsp;gamma = 0.99<br> &nbsp;&nbsp;&nbsp;alpha = 0.5<br> &nbsp;&nbsp;&nbsp;total_reward_t = 0<br> <br> &nbsp;&nbsp;&nbsp;while (memory.len() &gt; 0):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(state, action, reward) = memory.sample()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = gamma * total_reward_t &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 時間割引率をかける<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Q関数を更新<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table[state, action] = q_table[state, action] + alpha*(reward+total_reward_t-q_table[state, action])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = total_reward_t + reward &nbsp;&nbsp;&nbsp;# ステップtより先でもらえた報酬の合計を更新<br> <br> &nbsp;&nbsp;&nbsp;return q_table<br> <br> # [4]1試行の各ステップの行動を保存しておくメモリクラス<br> class Memory:<br> &nbsp;&nbsp;&nbsp;def __init__(self, max_size=400):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer = deque(maxlen=max_size)<br> <br> &nbsp;&nbsp;&nbsp;def add(self, experience):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer.append(experience)<br> <br> &nbsp;&nbsp;&nbsp;def sample(self):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self.buffer.pop() &nbsp;# 最後尾のメモリを取り出す<br> <br> &nbsp;&nbsp;&nbsp;def len(self):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return len(self.buffer)<br> <br> # エージェント パラメータ設定--------------------------------------------------------<br> <br> # バッファーメモリの大きさ<br> memory = Memory(max_size=400)<br> num_dizitized = 10<br> <br> # 前回のテーブルが存在すれば読み込み(状態を6分割^(5変数)にデジタル変換してQ関数(表)を作成)<br> if os.path.exists('q_table.csv'):<br> &nbsp;&nbsp;&nbsp;q_table = np.loadtxt('q_table.csv', dtype=float, delimiter=',')<br> &nbsp;&nbsp;&nbsp;print("parameter loaded.")<br> else:<br> &nbsp;&nbsp;&nbsp;q_table = np.random.uniform(low=0.0, high=1.0, size=(num_dizitized**6, 2))<br> <br> <br> # JPY残高を参照する関数 -------------------------------------<br> def get_asset():<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetch_balance()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br> &nbsp;&nbsp;&nbsp;return value<br> <br> # JPY証拠金を参照する関数 -------------------------------------<br> def get_colla():<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.privateGetGetcollateral()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br> &nbsp;&nbsp;&nbsp;return value<br> <br> # JPY証拠金変動履歴を参照する関数 -------------------------------------<br> def get_collateralhistory():<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = api.getcollateralhistory(product_code=PAIR, count=1)[0]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br> &nbsp;&nbsp;&nbsp;return value<br> <br> # 板情報から実効Ask/Bid(=指値を入れる基準値)を計算する関数 -------------------------------------<br> def get_effective_tick(size_thru, rate_ask, size_ask, rate_bid, size_bid):<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetchOrderBook(PAIR)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br> <br> &nbsp;&nbsp;&nbsp;i = 0<br> &nbsp;&nbsp;&nbsp;s = 0<br> &nbsp;&nbsp;&nbsp;while s &lt;= size_thru:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['bids'][i][0] == rate_bid:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1] - size_bid<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i += 1<br> <br> &nbsp;&nbsp;&nbsp;j = 0<br> &nbsp;&nbsp;&nbsp;t = 0<br> &nbsp;&nbsp;&nbsp;while t &lt;= size_thru:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['asks'][j][0] == rate_ask:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1] - size_ask<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j += 1<br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br> &nbsp;&nbsp;&nbsp;return {'bid': value['bids'][i-1][0], 'ask': value['asks'][j-1][0]}<br> <br> # 自分のポジションを取得する関数 -------------------------------------<br> def getposition():<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ポジション - 確認')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getpositions( params = { "product_code" : PAIR })<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br> &nbsp;&nbsp;&nbsp;return value<br> <br> # 成行注文する関数 -------------------------------------<br> def market(side, size):<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('成行注文 - 実行')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'market', side = side, amount = size)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br> &nbsp;&nbsp;&nbsp;return value<br> <br> # 指値注文する関数 -------------------------------------<br> def limit(side, size, price):<br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('指値注文 - 実行')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'limit', side = side, amount = size, price = price)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1.5)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br> &nbsp;&nbsp;&nbsp;return value<br> <br> # 注文をキャンセルする関数 -------------------------------------<br> def cancel(id):<br> &nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('キャンセル - 実行')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.cancelOrder(symbol = PAIR, id = id)<br> &nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 指値が約定していた(=キャンセルが通らなかった)場合、<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 注文情報を更新(約定済み)して返す<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = get_status(id)<br> <br> &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br> &nbsp;&nbsp;&nbsp;return value<br> <br> # 指定した注文idのステータスを参照する関数 -------------------------------------<br> def get_status(id):<br> <br> &nbsp;&nbsp;&nbsp;err_cnt = 0<br> <br> &nbsp;&nbsp;&nbsp;if PAIR == 'BTC/JPY':<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = 'BTC_JPY'<br> &nbsp;&nbsp;&nbsp;else:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = PAIR<br> <br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getchildorders(params = {'product_code': PRODUCT, 'child_order_acceptance_id': id})[0]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ステータスが受け取れない為61秒待機。')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(61)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt += 1<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if err_cnt == 5:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt = 0<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {'id' : 'null'}<br> <br> &nbsp;&nbsp;&nbsp;# APIで受け取った値を読み換える<br> &nbsp;&nbsp;&nbsp;if value['child_order_state'] == 'ACTIVE':<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'open'<br> &nbsp;&nbsp;&nbsp;elif value['child_order_state'] == 'COMPLETED':<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'closed'<br> &nbsp;&nbsp;&nbsp;else:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = value['child_order_state']<br> <br> &nbsp;&nbsp;&nbsp;# 未約定量を計算する<br> &nbsp;&nbsp;&nbsp;remaining = float(value['size']) - float(value['executed_size'])<br> <br> &nbsp;&nbsp;&nbsp;time.sleep(0.1)<br> &nbsp;&nbsp;&nbsp;return {'id': value['child_order_acceptance_id'], 'status': status, 'filled': value['executed_size'], 'remaining': remaining, 'amount': value['size'], 'price': value['price']}<br> <br> #------------------------------------------------------------------------------#<br> <br> # 未約定量が存在することを示すフラグ<br> remaining_ask_flag = 0<br> remaining_bid_flag = 0<br> <br> #------------------------------------------------------------------------------#<br> <br> logger.info('--------TradeStart--------')<br> logger.info('BOT TYPE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: MarketMaker @ bitFlyer')<br> logger.info('SYMBOL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(PAIR))<br> logger.info('LOT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0} {1}'.format(LOT, COIN))<br> <br> # 残高取得<br> TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br> logger.info('--------------------------')<br> logger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(TOTAL))<br> <br> # 現在の状態tを取得<br> tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br> ask = float(tick['ask'])<br> bid = float(tick['bid'])<br> spread = (ask - bid) / bid<br> <br> result = bitflyer.fetch_ticker(symbol=PAIR)<br> total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br> observation = ask, bid, spread, total_ask_depth, total_bid_depth, TOTAL<br> state = digitize_state(observation)<br> <br> prev_change = get_collateralhistory()['change']<br> trade_bid = {}<br> trade_ask = {}<br> trades = []<br> action = np.argmax(q_table[state])<br> before_position = float(get_colla()['open_position_pnl'])<br> episode = 0<br> total_episode = 0<br> reward = 0.0<br> episode_reward = 0<br> EARNING = 0<br> contract = 'false'<br> <br> long_cnt = 0<br> short_cnt = 0<br> <br> # 利確設定 <br> CONTRACT_PRICE = 100<br> <br> # 損切設定 <br> FAILURE_PRICE = -100<br> <br> position_flag = 0<br> #------------------------------- メインループ -------------------------------------#<br> while True:<br> <br> #------------------------------- エージェントアクション -------------------------------------#<br> &nbsp;&nbsp;&nbsp;# 買い<br> &nbsp;&nbsp;&nbsp;if action == 0:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 0<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------long-----')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_bid = market('buy', LOT)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_bid)<br> <br> &nbsp;&nbsp;&nbsp;# 売り<br> &nbsp;&nbsp;&nbsp;if action == 1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 1<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------short-----')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_ask = market('sell', LOT)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_ask)<br> <br> #------------------------------- 報酬 -------------------------------------#<br> <br> &nbsp;&nbsp;&nbsp;logger.info('------経過観察中-----')<br> &nbsp;&nbsp;&nbsp;while True:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 実行後の評価損益を記録<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;after_TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------エージェントの設定値--------')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('実行回数 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(episode))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ACTION &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(action))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------リアルタイム残高--------')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(after_TOTAL))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (利確)報酬を記録<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change = get_collateralhistory()['change']<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(prev_change))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(change))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if change != prev_change:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev_change = change<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = change<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (含益)報酬を記録<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(before_position))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(get_colla()['open_position_pnl']))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if before_position != float(get_colla()['open_position_pnl']):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = float(reward) + float(get_colla()['open_position_pnl'])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_position = float(get_colla()['open_position_pnl'])<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 総合利益パーセント算出<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOTAL_PERCENT = float(after_TOTAL/TOTAL) * 100.0<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 収益<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EARNING = after_TOTAL - TOTAL<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode_reward = float(episode_reward) + reward<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------評価--------')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('REWARD &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(float(reward)))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL REWARD &nbsp;&nbsp;: {0}'.format(float(episode_reward)))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('EARNING &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {:+f}'.format(float(EARNING)))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL PERCENT &nbsp;: {0} %'.format(TOTAL_PERCENT))<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 利益+2%または損失-2%に到達したら利確<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if FAILURE_PRICE &gt;= EARNING or EARNING &gt;= CONTRACT_PRICE:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for trade in trades:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 'null' != trade['id']:<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 0:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('sell', LOT)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('buy', LOT)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------約定完了-----')<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 現在の状態tを取得<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ask = float(tick['ask'])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bid = float(tick['bid'])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spread = (ask - bid) / bid<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = bitflyer.fetch_ticker(symbol=PAIR)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observation = ask, bid, spread, total_ask_depth, total_bid_depth, after_TOTAL<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = digitize_state(observation)<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# メモリに、現在の状態と行った行動、得た報酬を記録する<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memory.add((state, action, reward))<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 約定されたタイミングでテーブル更新<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if contract == 'true':<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('約定確定')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table = update_Qtable_montecarlo(q_table, memory)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = np.argmax(q_table[state])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = np.array(q_table)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.savetxt("q_table.csv", data, delimiter=',')<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'false'<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 次ステップへ行動と状態を更新<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_state = digitize_state(observation) &nbsp;# t+1での観測状態を、離散値に変換<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = get_action(next_state, episode) &nbsp;# 次の行動a_{t+1}を求める<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = next_action &nbsp;# a_{t+1}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = next_state &nbsp;# s_{t+1}<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# エピソード記録<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode += 1<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_episode += 1<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 報酬リセット<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = 0<br> <br> <br> <br> </code></pre> </html>
json metadata{"tags":["bitcoin","fx","bot","japanese","jp-newbie"],"links":["https://note.mu/magimagi1223/n/n5fba7501dcfd"],"app":"steemit/0.1","format":"html"}
parent author
parent permlinkbitcoin
permlink2kdc6b-bitcoin-fx
title強化学習によるBitcoin FXの攻略 ソースコード公開
Transaction InfoBlock #25755291/Trx 9f2e6ec4082ae4579be1c41e875178e617cd2d67
View Raw JSON Data
{
  "block": 25755291,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "<html>\n<h1>始めに言っておくと、<strong>大損害を生むソースコードですので絶対に使用しないように!</strong></h1>\n<p><br></p>\n<p>また、本ソースコードで使用している取引所の売買を実行するメソッドは、Bot実装で有名なUKI氏のブログより参考にさせていただきました。</p>\n<p>https://note.mu/magimagi1223/n/n5fba7501dcfd</p>\n<p><br></p>\n<p>まず仕組みから説明する。</p>\n<p>強化学習におけるエージェントのアクションはたったの以下2つ。</p>\n<p>・Long</p>\n<p>・Short</p>\n<p>学習モデルはモンテカルロ法で、利確したタイミングで初めてモデル(エージェントの脳みそ)を更新する。</p>\n<p>そのため、利確するまではいつまでもモデルの更新はない。</p>\n<p>これだけでもわかる通り、とても学習するのに時間がかかる!</p>\n<p>流れは以下の通りだ。</p>\n<p>1.エージェントが買う or 売る</p>\n<p>2.利確されるまで3.をループ</p>\n<p>3.以下5つをモデル更新用のメモリに蓄積</p>\n<p> 「リアルタイムの収益+-」</p>\n<p> 「ask」</p>\n<p> 「bid」</p>\n<p> 「spread」</p>\n<p> 「 total bid depth ( 売り注文総数) 」</p>\n<p> 「 total ask depth (買い注文総数) 」</p>\n<p>4.利確されたらモデルを更新</p>\n<p><br></p>\n<p>以下、ソースコードになる。アドバイスがあればお願いしたい。</p>\n<p>※このコードを使用する際に発生した損失について責任を負いません。このコードはサンプル目的のみを対象としています - 実際の取引にこのコードを使用しないでください。</p>\n<pre><code>#!/usr/bin/python3<br>\n# coding: utf-8<br>\n<br>\nimport datetime<br>\nimport time<br>\nimport os<br>\nimport numpy as np<br>\nimport ccxt<br>\nimport pybitflyer<br>\nfrom collections import deque<br>\nkey = 'xxxxxxxxxxxxxxxxxxxxxxx'<br>\nsecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'<br>\n<br>\nbitflyer = ccxt.bitflyer({<br>\n'apiKey': key,<br>\n'secret': secret,<br>\n})<br>\n<br>\napi = pybitflyer.API(key, secret)<br>\n<br>\n# 取引する通貨、シンボルを設定<br>\nCOIN = 'BTC'<br>\nPAIR = 'BTCJPY28SEP2018'<br>\n<br>\n# ロット(単位はBTC)<br>\nLOT = 0.05<br>\n<br>\n# 最小注文数(取引所の仕様に応じて設定)<br>\nAMOUNT_MIN = 0.001<br>\n<br>\n# 数量X(この数量よりも下に指値をおく)<br>\nAMOUNT_THRU = 0.01<br>\n<br>\n# 実効Ask/BidからDELTA離れた位置に指値をおく<br>\nDELTA = 1<br>\n<br>\n# レバレッジ設定<br>\nLEVERAGE = 1.0<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n#log設定<br>\nimport logging<br>\nlogger = logging.getLogger('LoggingTest')<br>\nlogger.setLevel(10)<br>\nfh = logging.FileHandler('log_mm_bf_' + datetime.datetime.now().strftime('%Y%m%d') + '_' + datetime.datetime.now().strftime('%H%M%S') + '.log')<br>\nlogger.addHandler(fh)<br>\nsh = logging.StreamHandler()<br>\nlogger.addHandler(sh)<br>\nformatter = logging.Formatter('%(asctime)s: %(message)s', datefmt=\"%Y-%m-%d %H:%M:%S\")<br>\nfh.setFormatter(formatter)<br>\nsh.setFormatter(formatter)<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n# [1]Q関数を離散化して定義する関数 ------------<br>\n# 観測した状態を離散値にデジタル変換する<br>\ndef bins(clip_min, clip_max, num):<br>\n &nbsp;&nbsp;&nbsp;return np.linspace(clip_min, clip_max, num + 1)[1:-1]<br>\n<br>\n# 各値を離散値に変換<br>\ndef digitize_state(observation):<br>\n &nbsp;&nbsp;&nbsp;ask, bid, spread, total_ask_depth, total_bid_depth, balance = observation<br>\n &nbsp;&nbsp;&nbsp;digitized = [<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(ask, bins=bins(0.0, 1.0, num_dizitized)),<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(bid, bins=bins(0.0, 1.0, num_dizitized)),<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(spread, bins=bins(0.0, 1.0, num_dizitized)),<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_ask_depth, bins=bins(0.0, 1.0, num_dizitized)),<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(total_bid_depth, bins=bins(0.0, 1.0, num_dizitized)),<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.digitize(balance, bins=bins(0.0, 1.0, num_dizitized))<br>\n &nbsp;&nbsp;&nbsp;]<br>\n &nbsp;&nbsp;&nbsp;return sum([x * (num_dizitized**i) for i, x in enumerate(digitized)])<br>\n<br>\n# [2]行動a(t)を求める関数 -------------------------------------<br>\ndef get_action(next_state, episode):<br>\n<br>\n &nbsp;&nbsp;&nbsp;#徐々に最適行動のみをとる、ε-greedy法<br>\n &nbsp;&nbsp;&nbsp;epsilon = 0.5 * (1 / (episode + 1))<br>\n &nbsp;&nbsp;&nbsp;if epsilon &lt;= np.random.uniform(0, 1):<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.argmax(q_table[next_state])<br>\n &nbsp;&nbsp;&nbsp;else:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = np.random.choice([0, 1])<br>\n &nbsp;&nbsp;&nbsp;return next_action<br>\n<br>\n# [3]Qテーブルを更新する(モンテカルロ法) *Qlearningと異なる* -------------------------------------<br>\ndef update_Qtable_montecarlo(q_table, memory):<br>\n &nbsp;&nbsp;&nbsp;gamma = 0.99<br>\n &nbsp;&nbsp;&nbsp;alpha = 0.5<br>\n &nbsp;&nbsp;&nbsp;total_reward_t = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;while (memory.len() &gt; 0):<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(state, action, reward) = memory.sample()<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = gamma * total_reward_t &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 時間割引率をかける<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Q関数を更新<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table[state, action] = q_table[state, action] + alpha*(reward+total_reward_t-q_table[state, action])<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_reward_t = total_reward_t + reward &nbsp;&nbsp;&nbsp;# ステップtより先でもらえた報酬の合計を更新<br>\n<br>\n &nbsp;&nbsp;&nbsp;return q_table<br>\n<br>\n# [4]1試行の各ステップの行動を保存しておくメモリクラス<br>\nclass Memory:<br>\n &nbsp;&nbsp;&nbsp;def __init__(self, max_size=400):<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer = deque(maxlen=max_size)<br>\n<br>\n &nbsp;&nbsp;&nbsp;def add(self, experience):<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.buffer.append(experience)<br>\n<br>\n &nbsp;&nbsp;&nbsp;def sample(self):<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self.buffer.pop() &nbsp;# 最後尾のメモリを取り出す<br>\n<br>\n &nbsp;&nbsp;&nbsp;def len(self):<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return len(self.buffer)<br>\n<br>\n# エージェント パラメータ設定--------------------------------------------------------<br>\n<br>\n# バッファーメモリの大きさ<br>\nmemory = Memory(max_size=400)<br>\nnum_dizitized = 10<br>\n<br>\n# 前回のテーブルが存在すれば読み込み(状態を6分割^(5変数)にデジタル変換してQ関数(表)を作成)<br>\nif os.path.exists('q_table.csv'):<br>\n &nbsp;&nbsp;&nbsp;q_table = np.loadtxt('q_table.csv', dtype=float, delimiter=',')<br>\n &nbsp;&nbsp;&nbsp;print(\"parameter loaded.\")<br>\nelse:<br>\n &nbsp;&nbsp;&nbsp;q_table = np.random.uniform(low=0.0, high=1.0, size=(num_dizitized**6, 2))<br>\n<br>\n<br>\n# JPY残高を参照する関数 -------------------------------------<br>\ndef get_asset():<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetch_balance()<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n# JPY証拠金を参照する関数 -------------------------------------<br>\ndef get_colla():<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.privateGetGetcollateral()<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n# JPY証拠金変動履歴を参照する関数 -------------------------------------<br>\ndef get_collateralhistory():<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = api.getcollateralhistory(product_code=PAIR, count=1)[0]<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1)<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n# 板情報から実効Ask/Bid(=指値を入れる基準値)を計算する関数 -------------------------------------<br>\ndef get_effective_tick(size_thru, rate_ask, size_ask, rate_bid, size_bid):<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.fetchOrderBook(PAIR)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br>\n<br>\n &nbsp;&nbsp;&nbsp;i = 0<br>\n &nbsp;&nbsp;&nbsp;s = 0<br>\n &nbsp;&nbsp;&nbsp;while s &lt;= size_thru:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['bids'][i][0] == rate_bid:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1] - size_bid<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += value['bids'][i][1]<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i += 1<br>\n<br>\n &nbsp;&nbsp;&nbsp;j = 0<br>\n &nbsp;&nbsp;&nbsp;t = 0<br>\n &nbsp;&nbsp;&nbsp;while t &lt;= size_thru:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if value['asks'][j][0] == rate_ask:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1] - size_ask<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += value['asks'][j][1]<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j += 1<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br>\n &nbsp;&nbsp;&nbsp;return {'bid': value['bids'][i-1][0], 'ask': value['asks'][j-1][0]}<br>\n<br>\n# 自分のポジションを取得する関数 -------------------------------------<br>\ndef getposition():<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ポジション - 確認')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getpositions( params = { \"product_code\" : PAIR })<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n# 成行注文する関数 -------------------------------------<br>\ndef market(side, size):<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('成行注文 - 実行')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'market', side = side, amount = size)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(2)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.5)<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n# 指値注文する関数 -------------------------------------<br>\ndef limit(side, size, price):<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('指値注文 - 実行')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.create_order(PAIR, type = 'limit', side = side, amount = size, price = price)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(1.5)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = {'id' : 'null'}<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n# 注文をキャンセルする関数 -------------------------------------<br>\ndef cancel(id):<br>\n &nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('キャンセル - 実行')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.cancelOrder(symbol = PAIR, id = id)<br>\n &nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 指値が約定していた(=キャンセルが通らなかった)場合、<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 注文情報を更新(約定済み)して返す<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = get_status(id)<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(1.5)<br>\n &nbsp;&nbsp;&nbsp;return value<br>\n<br>\n# 指定した注文idのステータスを参照する関数 -------------------------------------<br>\ndef get_status(id):<br>\n<br>\n &nbsp;&nbsp;&nbsp;err_cnt = 0<br>\n<br>\n &nbsp;&nbsp;&nbsp;if PAIR == 'BTC/JPY':<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = 'BTC_JPY'<br>\n &nbsp;&nbsp;&nbsp;else:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PRODUCT = PAIR<br>\n<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = bitflyer.private_get_getchildorders(params = {'product_code': PRODUCT, 'child_order_acceptance_id': id})[0]<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ステータスが受け取れない為61秒待機。')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(e)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(61)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt += 1<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if err_cnt == 5:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_cnt = 0<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {'id' : 'null'}<br>\n<br>\n &nbsp;&nbsp;&nbsp;# APIで受け取った値を読み換える<br>\n &nbsp;&nbsp;&nbsp;if value['child_order_state'] == 'ACTIVE':<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'open'<br>\n &nbsp;&nbsp;&nbsp;elif value['child_order_state'] == 'COMPLETED':<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = 'closed'<br>\n &nbsp;&nbsp;&nbsp;else:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status = value['child_order_state']<br>\n<br>\n &nbsp;&nbsp;&nbsp;# 未約定量を計算する<br>\n &nbsp;&nbsp;&nbsp;remaining = float(value['size']) - float(value['executed_size'])<br>\n<br>\n &nbsp;&nbsp;&nbsp;time.sleep(0.1)<br>\n &nbsp;&nbsp;&nbsp;return {'id': value['child_order_acceptance_id'], 'status': status, 'filled': value['executed_size'], 'remaining': remaining, 'amount': value['size'], 'price': value['price']}<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n<br>\n# 未約定量が存在することを示すフラグ<br>\nremaining_ask_flag = 0<br>\nremaining_bid_flag = 0<br>\n<br>\n#------------------------------------------------------------------------------#<br>\n<br>\nlogger.info('--------TradeStart--------')<br>\nlogger.info('BOT TYPE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: MarketMaker @ bitFlyer')<br>\nlogger.info('SYMBOL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(PAIR))<br>\nlogger.info('LOT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0} {1}'.format(LOT, COIN))<br>\n<br>\n# 残高取得<br>\nTOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br>\nlogger.info('--------------------------')<br>\nlogger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(TOTAL))<br>\n<br>\n# 現在の状態tを取得<br>\ntick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br>\nask = float(tick['ask'])<br>\nbid = float(tick['bid'])<br>\nspread = (ask - bid) / bid<br>\n<br>\nresult = bitflyer.fetch_ticker(symbol=PAIR)<br>\ntotal_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br>\nobservation = ask, bid, spread, total_ask_depth, total_bid_depth, TOTAL<br>\nstate = digitize_state(observation)<br>\n<br>\nprev_change = get_collateralhistory()['change']<br>\ntrade_bid = {}<br>\ntrade_ask = {}<br>\ntrades = []<br>\naction = np.argmax(q_table[state])<br>\nbefore_position = float(get_colla()['open_position_pnl'])<br>\nepisode = 0<br>\ntotal_episode = 0<br>\nreward = 0.0<br>\nepisode_reward = 0<br>\nEARNING = 0<br>\ncontract = 'false'<br>\n<br>\nlong_cnt = 0<br>\nshort_cnt = 0<br>\n<br>\n# 利確設定 <br>\nCONTRACT_PRICE = 100<br>\n<br>\n# 損切設定 <br>\nFAILURE_PRICE = -100<br>\n<br>\nposition_flag = 0<br>\n#------------------------------- メインループ -------------------------------------#<br>\nwhile True:<br>\n<br>\n#------------------------------- エージェントアクション -------------------------------------#<br>\n &nbsp;&nbsp;&nbsp;# 買い<br>\n &nbsp;&nbsp;&nbsp;if action == 0:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 0<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------long-----')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_bid = market('buy', LOT)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_bid)<br>\n<br>\n &nbsp;&nbsp;&nbsp;# 売り<br>\n &nbsp;&nbsp;&nbsp;if action == 1:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position_flag = 1<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------short-----')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade_ask = market('sell', LOT)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trades.append(trade_ask)<br>\n<br>\n#------------------------------- 報酬 -------------------------------------#<br>\n<br>\n &nbsp;&nbsp;&nbsp;logger.info('------経過観察中-----')<br>\n &nbsp;&nbsp;&nbsp;while True:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 実行後の評価損益を記録<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;after_TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------エージェントの設定値--------')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('実行回数 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(episode))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('ACTION &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(action))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------リアルタイム残高--------')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(after_TOTAL))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (利確)報酬を記録<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change = get_collateralhistory()['change']<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(prev_change))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('利確報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(change))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if change != prev_change:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev_change = change<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = change<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# (含益)報酬を記録<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行前 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(before_position))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('含益報酬実行後 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(get_colla()['open_position_pnl']))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if before_position != float(get_colla()['open_position_pnl']):<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = float(reward) + float(get_colla()['open_position_pnl'])<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_position = float(get_colla()['open_position_pnl'])<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 総合利益パーセント算出<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TOTAL_PERCENT = float(after_TOTAL/TOTAL) * 100.0<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 収益<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EARNING = after_TOTAL - TOTAL<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode_reward = float(episode_reward) + reward<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('--------評価--------')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('REWARD &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {0}'.format(float(reward)))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL REWARD &nbsp;&nbsp;: {0}'.format(float(episode_reward)))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('EARNING &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: {:+f}'.format(float(EARNING)))<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('TOTAL PERCENT &nbsp;: {0} %'.format(TOTAL_PERCENT))<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 利益+2%または損失-2%に到達したら利確<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if FAILURE_PRICE &gt;= EARNING or EARNING &gt;= CONTRACT_PRICE:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for trade in trades:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 'null' != trade['id']:<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 0:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('sell', LOT)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if position_flag == 1:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trade = market('buy', LOT)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'true'<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('------約定完了-----')<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 現在の状態tを取得<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ask = float(tick['ask'])<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bid = float(tick['bid'])<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spread = (ask - bid) / bid<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = bitflyer.fetch_ticker(symbol=PAIR)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;observation = ask, bid, spread, total_ask_depth, total_bid_depth, after_TOTAL<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = digitize_state(observation)<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# メモリに、現在の状態と行った行動、得た報酬を記録する<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memory.add((state, action, reward))<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 約定されたタイミングでテーブル更新<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if contract == 'true':<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info('約定確定')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q_table = update_Qtable_montecarlo(q_table, memory)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = np.argmax(q_table[state])<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = np.array(q_table)<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.savetxt(\"q_table.csv\", data, delimiter=',')<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contract = 'false'<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break<br>\n<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 次ステップへ行動と状態を更新<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_state = digitize_state(observation) &nbsp;# t+1での観測状態を、離散値に変換<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_action = get_action(next_state, episode) &nbsp;# 次の行動a_{t+1}を求める<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action = next_action &nbsp;# a_{t+1}<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state = next_state &nbsp;# s_{t+1}<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# エピソード記録<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;episode += 1<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total_episode += 1<br>\n &nbsp;&nbsp;&nbsp;<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 報酬リセット<br>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reward = 0<br>\n<br>\n<br>\n<br>\n</code></pre>\n</html>",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"fx\",\"bot\",\"japanese\",\"jp-newbie\"],\"links\":[\"https://note.mu/magimagi1223/n/n5fba7501dcfd\"],\"app\":\"steemit/0.1\",\"format\":\"html\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "2kdc6b-bitcoin-fx",
      "title": "強化学習によるBitcoin FXの攻略 ソースコード公開"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:55:33",
  "trx_id": "9f2e6ec4082ae4579be1c41e875178e617cd2d67",
  "trx_in_block": 27,
  "virtual_op": 0
}
2018/09/07 15:49:24
authorgtg
permlinkflourishing-steem-eli5
voterjianty
weight10000 (100.00%)
Transaction InfoBlock #25755168/Trx c4bfcaaeaec416c846e33e512e9e4160e079450f
View Raw JSON Data
{
  "block": 25755168,
  "op": [
    "vote",
    {
      "author": "gtg",
      "permlink": "flourishing-steem-eli5",
      "voter": "jianty",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:49:24",
  "trx_id": "c4bfcaaeaec416c846e33e512e9e4160e079450f",
  "trx_in_block": 12,
  "virtual_op": 0
}
jiantypublished a new post: 2kdc6b-bitcoin-fx
2018/09/07 15:36:06
authorjianty
body<html> <h1>始めに言っておくと、<strong>大損害を生むソースコードですので絶対に使用しないように!</strong></h1> <p><br></p> <p>また、本ソースコードで使用している取引所の売買を実行するメソッドは、Bot実装で有名なUKI氏のブログより参考にさせていただきました。</p> <p>https://note.mu/magimagi1223/n/n5fba7501dcfd</p> <p><br></p> <p>まず仕組みから説明する。</p> <p>強化学習におけるエージェントのアクションはたったの以下2つ。</p> <p>・Long</p> <p>・Short</p> <p>学習モデルはモンテカルロ法で、利確したタイミングで初めてモデル(エージェントの脳みそ)を更新する。</p> <p>そのため、利確するまではいつまでもモデルの更新はない。</p> <p>これだけでもわかる通り、とても学習するのに時間がかかる!</p> <p>流れは以下の通りだ。</p> <p>1.エージェントが買う or 売る</p> <p>2.利確されるまで3.をループ</p> <p>3.以下5つをモデル更新用のメモリに蓄積</p> <p> 「リアルタイムの収益+-」</p> <p> 「ask」</p> <p> 「bid」</p> <p> 「spread」</p> <p> 「 total bid depth ( 売り注文総数) 」</p> <p> 「 total ask depth (買い注文総数) 」</p> <p>4.利確されたらモデルを更新</p> <p><br></p> <p>以下、ソースコードになる。アドバイスがあればお願いしたい。</p> <pre><code> #!/usr/bin/python3 # coding: utf-8 import datetime import time import os import numpy as np import ccxt import pybitflyer from collections import deque key = 'xxxxxxxxxxxxxxxxxxxxxxx' secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx' bitflyer = ccxt.bitflyer({ 'apiKey': key, 'secret': secret, }) api = pybitflyer.API(key, secret) # 取引する通貨、シンボルを設定 COIN = 'BTC' PAIR = 'BTCJPY28SEP2018' # ロット(単位はBTC) LOT = 0.05 # 最小注文数(取引所の仕様に応じて設定) AMOUNT_MIN = 0.001 # 数量X(この数量よりも下に指値をおく) AMOUNT_THRU = 0.01 # 実効Ask/BidからDELTA離れた位置に指値をおく DELTA = 1 # レバレッジ設定 LEVERAGE = 1.0 #------------------------------------------------------------------------------# #log設定 import logging logger = logging.getLogger('LoggingTest') logger.setLevel(10) fh = logging.FileHandler('log_mm_bf_' + datetime.datetime.now().strftime('%Y%m%d') + '_' + datetime.datetime.now().strftime('%H%M%S') + '.log') logger.addHandler(fh) sh = logging.StreamHandler() logger.addHandler(sh) formatter = logging.Formatter('%(asctime)s: %(message)s', datefmt="%Y-%m-%d %H:%M:%S") fh.setFormatter(formatter) sh.setFormatter(formatter) #------------------------------------------------------------------------------# # [1]Q関数を離散化して定義する関数 ------------ # 観測した状態を離散値にデジタル変換する def bins(clip_min, clip_max, num): return np.linspace(clip_min, clip_max, num + 1)[1:-1] # 各値を離散値に変換 def digitize_state(observation): ask, bid, spread, total_ask_depth, total_bid_depth, balance = observation digitized = [ np.digitize(ask, bins=bins(0.0, 1.0, num_dizitized)), np.digitize(bid, bins=bins(0.0, 1.0, num_dizitized)), np.digitize(spread, bins=bins(0.0, 1.0, num_dizitized)), np.digitize(total_ask_depth, bins=bins(0.0, 1.0, num_dizitized)), np.digitize(total_bid_depth, bins=bins(0.0, 1.0, num_dizitized)), np.digitize(balance, bins=bins(0.0, 1.0, num_dizitized)) ] return sum([x * (num_dizitized**i) for i, x in enumerate(digitized)]) # [2]行動a(t)を求める関数 ------------------------------------- def get_action(next_state, episode): #徐々に最適行動のみをとる、ε-greedy法 epsilon = 0.5 * (1 / (episode + 1)) if epsilon <= np.random.uniform(0, 1): next_action = np.argmax(q_table[next_state]) else: next_action = np.random.choice([0, 1]) return next_action # [3]Qテーブルを更新する(モンテカルロ法) *Qlearningと異なる* ------------------------------------- def update_Qtable_montecarlo(q_table, memory): gamma = 0.99 alpha = 0.5 total_reward_t = 0 while (memory.len() > 0): (state, action, reward) = memory.sample() total_reward_t = gamma * total_reward_t # 時間割引率をかける # Q関数を更新 q_table[state, action] = q_table[state, action] + alpha*(reward+total_reward_t-q_table[state, action]) total_reward_t = total_reward_t + reward # ステップtより先でもらえた報酬の合計を更新 return q_table # [4]1試行の各ステップの行動を保存しておくメモリクラス class Memory: def __init__(self, max_size=400): self.buffer = deque(maxlen=max_size) def add(self, experience): self.buffer.append(experience) def sample(self): return self.buffer.pop() # 最後尾のメモリを取り出す def len(self): return len(self.buffer) # エージェント パラメータ設定-------------------------------------------------------- # バッファーメモリの大きさ memory = Memory(max_size=400) num_dizitized = 10 # 前回のテーブルが存在すれば読み込み(状態を6分割^(5変数)にデジタル変換してQ関数(表)を作成) if os.path.exists('q_table.csv'): q_table = np.loadtxt('q_table.csv', dtype=float, delimiter=',') print("parameter loaded.") else: q_table = np.random.uniform(low=0.0, high=1.0, size=(num_dizitized**6, 2)) # JPY残高を参照する関数 ------------------------------------- def get_asset(): while True: try: value = bitflyer.fetch_balance() break except Exception as e: logger.info(e) time.sleep(1) return value # JPY証拠金を参照する関数 ------------------------------------- def get_colla(): while True: try: value = bitflyer.privateGetGetcollateral() break except Exception as e: logger.info(e) time.sleep(1) return value # JPY証拠金変動履歴を参照する関数 ------------------------------------- def get_collateralhistory(): while True: try: value = api.getcollateralhistory(product_code=PAIR, count=1)[0] break except Exception as e: logger.info(e) time.sleep(1) return value # 板情報から実効Ask/Bid(=指値を入れる基準値)を計算する関数 ------------------------------------- def get_effective_tick(size_thru, rate_ask, size_ask, rate_bid, size_bid): while True: try: value = bitflyer.fetchOrderBook(PAIR) break except Exception as e: logger.info(e) time.sleep(2) i = 0 s = 0 while s <= size_thru: if value['bids'][i][0] == rate_bid: s += value['bids'][i][1] - size_bid else: s += value['bids'][i][1] i += 1 j = 0 t = 0 while t <= size_thru: if value['asks'][j][0] == rate_ask: t += value['asks'][j][1] - size_ask else: t += value['asks'][j][1] j += 1 time.sleep(0.5) return {'bid': value['bids'][i-1][0], 'ask': value['asks'][j-1][0]} # 自分のポジションを取得する関数 ------------------------------------- def getposition(): while True: try: logger.info('ポジション - 確認') value = bitflyer.private_get_getpositions( params = { "product_code" : PAIR }) break except Exception as e: logger.info(e) time.sleep(2) time.sleep(0.5) return value # 成行注文する関数 ------------------------------------- def market(side, size): while True: try: logger.info('成行注文 - 実行') value = bitflyer.create_order(PAIR, type = 'market', side = side, amount = size) break except Exception as e: logger.info(e) time.sleep(2) value = {'id' : 'null'} break time.sleep(0.5) return value # 指値注文する関数 ------------------------------------- def limit(side, size, price): while True: try: logger.info('指値注文 - 実行') value = bitflyer.create_order(PAIR, type = 'limit', side = side, amount = size, price = price) break except Exception as e: logger.info(e) time.sleep(1.5) value = {'id' : 'null'} break time.sleep(1.5) return value # 注文をキャンセルする関数 ------------------------------------- def cancel(id): try: logger.info('キャンセル - 実行') value = bitflyer.cancelOrder(symbol = PAIR, id = id) except Exception as e: logger.info(e) # 指値が約定していた(=キャンセルが通らなかった)場合、 # 注文情報を更新(約定済み)して返す value = get_status(id) time.sleep(1.5) return value # 指定した注文idのステータスを参照する関数 ------------------------------------- def get_status(id): err_cnt = 0 if PAIR == 'BTC/JPY': PRODUCT = 'BTC_JPY' else: PRODUCT = PAIR while True: try: value = bitflyer.private_get_getchildorders(params = {'product_code': PRODUCT, 'child_order_acceptance_id': id})[0] break except Exception as e: logger.info('ステータスが受け取れない為61秒待機。') logger.info(e) time.sleep(61) err_cnt += 1 if err_cnt == 5: err_cnt = 0 return {'id' : 'null'} # APIで受け取った値を読み換える if value['child_order_state'] == 'ACTIVE': status = 'open' elif value['child_order_state'] == 'COMPLETED': status = 'closed' else: status = value['child_order_state'] # 未約定量を計算する remaining = float(value['size']) - float(value['executed_size']) time.sleep(0.1) return {'id': value['child_order_acceptance_id'], 'status': status, 'filled': value['executed_size'], 'remaining': remaining, 'amount': value['size'], 'price': value['price']} #------------------------------------------------------------------------------# # 未約定量が存在することを示すフラグ remaining_ask_flag = 0 remaining_bid_flag = 0 #------------------------------------------------------------------------------# logger.info('--------TradeStart--------') logger.info('BOT TYPE : MarketMaker @ bitFlyer') logger.info('SYMBOL : {0}'.format(PAIR)) logger.info('LOT : {0} {1}'.format(LOT, COIN)) # 残高取得 TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl']) logger.info('--------------------------') logger.info('TOTAL : {0}'.format(TOTAL)) # 現在の状態tを取得 tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0) ask = float(tick['ask']) bid = float(tick['bid']) spread = (ask - bid) / bid result = bitflyer.fetch_ticker(symbol=PAIR) total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth'] observation = ask, bid, spread, total_ask_depth, total_bid_depth, TOTAL state = digitize_state(observation) prev_change = get_collateralhistory()['change'] trade_bid = {} trade_ask = {} trades = [] action = np.argmax(q_table[state]) before_position = float(get_colla()['open_position_pnl']) episode = 0 total_episode = 0 reward = 0.0 episode_reward = 0 EARNING = 0 contract = 'false' long_cnt = 0 short_cnt = 0 # 利確設定 CONTRACT_PRICE = 100 # 損切設定 FAILURE_PRICE = -100 position_flag = 0 #------------------------------- メインループ -------------------------------------# while True: #------------------------------- エージェントアクション -------------------------------------# # 買い if action == 0: position_flag = 0 logger.info('------long-----') trade_bid = market('buy', LOT) trades.append(trade_bid) # 売り if action == 1: position_flag = 1 logger.info('------short-----') trade_ask = market('sell', LOT) trades.append(trade_ask) #------------------------------- 報酬 -------------------------------------# logger.info('------経過観察中-----') while True: # 実行後の評価損益を記録 after_TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl']) logger.info('--------エージェントの設定値--------') logger.info('実行回数 : {0}'.format(episode)) logger.info('ACTION : {0}'.format(action)) logger.info('--------リアルタイム残高--------') logger.info('TOTAL : {0}'.format(after_TOTAL)) # (利確)報酬を記録 change = get_collateralhistory()['change'] logger.info('利確報酬実行前 : {0}'.format(prev_change)) logger.info('利確報酬実行後 : {0}'.format(change)) if change != prev_change: prev_change = change reward = change contract = 'true' # (含益)報酬を記録 logger.info('含益報酬実行前 : {0}'.format(before_position)) logger.info('含益報酬実行後 : {0}'.format(get_colla()['open_position_pnl'])) if before_position != float(get_colla()['open_position_pnl']): reward = float(reward) + float(get_colla()['open_position_pnl']) before_position = float(get_colla()['open_position_pnl']) # 総合利益パーセント算出 TOTAL_PERCENT = float(after_TOTAL/TOTAL) * 100.0 # 収益 EARNING = after_TOTAL - TOTAL episode_reward = float(episode_reward) + reward logger.info('--------評価--------') logger.info('REWARD : {0}'.format(float(reward))) logger.info('TOTAL REWARD : {0}'.format(float(episode_reward))) logger.info('EARNING : {:+f}'.format(float(EARNING))) logger.info('TOTAL PERCENT : {0} %'.format(TOTAL_PERCENT)) # 利益+2%または損失-2%に到達したら利確 if FAILURE_PRICE >= EARNING or EARNING >= CONTRACT_PRICE: for trade in trades: if 'null' != trade['id']: if position_flag == 0: trade = market('sell', LOT) contract = 'true' if position_flag == 1: trade = market('buy', LOT) contract = 'true' logger.info('------約定完了-----') # 現在の状態tを取得 tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0) ask = float(tick['ask']) bid = float(tick['bid']) spread = (ask - bid) / bid result = bitflyer.fetch_ticker(symbol=PAIR) total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth'] observation = ask, bid, spread, total_ask_depth, total_bid_depth, after_TOTAL state = digitize_state(observation) # メモリに、現在の状態と行った行動、得た報酬を記録する memory.add((state, action, reward)) # 約定されたタイミングでテーブル更新 if contract == 'true': logger.info('約定確定') q_table = update_Qtable_montecarlo(q_table, memory) action = np.argmax(q_table[state]) data = np.array(q_table) np.savetxt("q_table.csv", data, delimiter=',') contract = 'false' break else: # 次ステップへ行動と状態を更新 next_state = digitize_state(observation) # t+1での観測状態を、離散値に変換 next_action = get_action(next_state, episode) # 次の行動a_{t+1}を求める action = next_action # a_{t+1} state = next_state # s_{t+1} # エピソード記録 episode += 1 total_episode += 1 # 報酬リセット reward = 0 </code></pre> </html>
json metadata{"tags":["bitcoin","fx","bot","japanese","jp-newbie"],"links":["https://note.mu/magimagi1223/n/n5fba7501dcfd"],"app":"steemit/0.1","format":"html"}
parent author
parent permlinkbitcoin
permlink2kdc6b-bitcoin-fx
title強化学習によるBitcoin FXの攻略 ソースコード公開
Transaction InfoBlock #25754902/Trx 137521c67080de29694b3c9afc29d8add8cf2ad9
View Raw JSON Data
{
  "block": 25754902,
  "op": [
    "comment",
    {
      "author": "jianty",
      "body": "<html>\n<h1>始めに言っておくと、<strong>大損害を生むソースコードですので絶対に使用しないように!</strong></h1>\n<p><br></p>\n<p>また、本ソースコードで使用している取引所の売買を実行するメソッドは、Bot実装で有名なUKI氏のブログより参考にさせていただきました。</p>\n<p>https://note.mu/magimagi1223/n/n5fba7501dcfd</p>\n<p><br></p>\n<p>まず仕組みから説明する。</p>\n<p>強化学習におけるエージェントのアクションはたったの以下2つ。</p>\n<p>・Long</p>\n<p>・Short</p>\n<p>学習モデルはモンテカルロ法で、利確したタイミングで初めてモデル(エージェントの脳みそ)を更新する。</p>\n<p>そのため、利確するまではいつまでもモデルの更新はない。</p>\n<p>これだけでもわかる通り、とても学習するのに時間がかかる!</p>\n<p>流れは以下の通りだ。</p>\n<p>1.エージェントが買う or 売る</p>\n<p>2.利確されるまで3.をループ</p>\n<p>3.以下5つをモデル更新用のメモリに蓄積</p>\n<p> 「リアルタイムの収益+-」</p>\n<p> 「ask」</p>\n<p> 「bid」</p>\n<p> 「spread」</p>\n<p> 「 total bid depth ( 売り注文総数) 」</p>\n<p> 「 total ask depth (買い注文総数) 」</p>\n<p>4.利確されたらモデルを更新</p>\n<p><br></p>\n<p>以下、ソースコードになる。アドバイスがあればお願いしたい。</p>\n<pre><code>\n#!/usr/bin/python3\n# coding: utf-8\n\nimport datetime\nimport time\nimport os\nimport numpy as np\nimport ccxt\nimport pybitflyer\nfrom collections import deque\nkey = 'xxxxxxxxxxxxxxxxxxxxxxx'\nsecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'\n\nbitflyer = ccxt.bitflyer({\n'apiKey': key,\n'secret': secret,\n})\n\napi = pybitflyer.API(key, secret)\n\n# 取引する通貨、シンボルを設定\nCOIN = 'BTC'\nPAIR = 'BTCJPY28SEP2018'\n\n# ロット(単位はBTC)\nLOT = 0.05\n\n# 最小注文数(取引所の仕様に応じて設定)\nAMOUNT_MIN = 0.001\n\n# 数量X(この数量よりも下に指値をおく)\nAMOUNT_THRU = 0.01\n\n# 実効Ask/BidからDELTA離れた位置に指値をおく\nDELTA = 1\n\n# レバレッジ設定\nLEVERAGE = 1.0\n\n#------------------------------------------------------------------------------#\n#log設定\nimport logging\nlogger = logging.getLogger('LoggingTest')\nlogger.setLevel(10)\nfh = logging.FileHandler('log_mm_bf_' + datetime.datetime.now().strftime('%Y%m%d') + '_' + datetime.datetime.now().strftime('%H%M%S') + '.log')\nlogger.addHandler(fh)\nsh = logging.StreamHandler()\nlogger.addHandler(sh)\nformatter = logging.Formatter('%(asctime)s: %(message)s', datefmt=\"%Y-%m-%d %H:%M:%S\")\nfh.setFormatter(formatter)\nsh.setFormatter(formatter)\n\n#------------------------------------------------------------------------------#\n# [1]Q関数を離散化して定義する関数 ------------\n# 観測した状態を離散値にデジタル変換する\ndef bins(clip_min, clip_max, num):\n    return np.linspace(clip_min, clip_max, num + 1)[1:-1]\n\n# 各値を離散値に変換\ndef digitize_state(observation):\n    ask, bid, spread, total_ask_depth, total_bid_depth, balance = observation\n    digitized = [\n        np.digitize(ask, bins=bins(0.0, 1.0, num_dizitized)),\n        np.digitize(bid, bins=bins(0.0, 1.0, num_dizitized)),\n        np.digitize(spread, bins=bins(0.0, 1.0, num_dizitized)),\n        np.digitize(total_ask_depth, bins=bins(0.0, 1.0, num_dizitized)),\n        np.digitize(total_bid_depth, bins=bins(0.0, 1.0, num_dizitized)),\n        np.digitize(balance, bins=bins(0.0, 1.0, num_dizitized))\n    ]\n    return sum([x * (num_dizitized**i) for i, x in enumerate(digitized)])\n\n# [2]行動a(t)を求める関数 -------------------------------------\ndef get_action(next_state, episode):\n\n    #徐々に最適行動のみをとる、ε-greedy法\n    epsilon = 0.5 * (1 / (episode + 1))\n    if epsilon <= np.random.uniform(0, 1):\n        next_action = np.argmax(q_table[next_state])\n    else:\n        next_action = np.random.choice([0, 1])\n    return next_action\n\n# [3]Qテーブルを更新する(モンテカルロ法) *Qlearningと異なる* -------------------------------------\ndef update_Qtable_montecarlo(q_table, memory):\n    gamma = 0.99\n    alpha = 0.5\n    total_reward_t = 0\n\n    while (memory.len() > 0):\n        (state, action, reward) = memory.sample()\n        total_reward_t = gamma * total_reward_t       # 時間割引率をかける\n        # Q関数を更新\n        q_table[state, action] = q_table[state, action] + alpha*(reward+total_reward_t-q_table[state, action])\n        total_reward_t = total_reward_t + reward    # ステップtより先でもらえた報酬の合計を更新\n\n    return q_table\n\n# [4]1試行の各ステップの行動を保存しておくメモリクラス\nclass Memory:\n    def __init__(self, max_size=400):\n        self.buffer = deque(maxlen=max_size)\n\n    def add(self, experience):\n        self.buffer.append(experience)\n\n    def sample(self):\n        return self.buffer.pop()  # 最後尾のメモリを取り出す\n\n    def len(self):\n        return len(self.buffer)\n\n# エージェント パラメータ設定--------------------------------------------------------\n\n# バッファーメモリの大きさ\nmemory = Memory(max_size=400)\nnum_dizitized = 10\n\n# 前回のテーブルが存在すれば読み込み(状態を6分割^(5変数)にデジタル変換してQ関数(表)を作成)\nif os.path.exists('q_table.csv'):\n    q_table = np.loadtxt('q_table.csv', dtype=float, delimiter=',')\n    print(\"parameter loaded.\")\nelse:\n    q_table = np.random.uniform(low=0.0, high=1.0, size=(num_dizitized**6, 2))\n\n\n# JPY残高を参照する関数 -------------------------------------\ndef get_asset():\n\n    while True:\n        try:\n            value = bitflyer.fetch_balance()\n            break\n        except Exception as e:\n            logger.info(e)\n            time.sleep(1)\n    return value\n\n# JPY証拠金を参照する関数 -------------------------------------\ndef get_colla():\n\n    while True:\n        try:\n            value = bitflyer.privateGetGetcollateral()\n            break\n        except Exception as e:\n            logger.info(e)\n            time.sleep(1)\n    return value\n\n# JPY証拠金変動履歴を参照する関数 -------------------------------------\ndef get_collateralhistory():\n\n    while True:\n        try:\n            value = api.getcollateralhistory(product_code=PAIR, count=1)[0]\n            break\n        except Exception as e:\n            logger.info(e)\n            time.sleep(1)\n    return value\n\n# 板情報から実効Ask/Bid(=指値を入れる基準値)を計算する関数 -------------------------------------\ndef get_effective_tick(size_thru, rate_ask, size_ask, rate_bid, size_bid):\n\n    while True:\n        try:\n            value = bitflyer.fetchOrderBook(PAIR)\n            break\n        except Exception as e:\n            logger.info(e)\n            time.sleep(2)\n\n    i = 0\n    s = 0\n    while s <= size_thru:\n        if value['bids'][i][0] == rate_bid:\n            s += value['bids'][i][1] - size_bid\n        else:\n            s += value['bids'][i][1]\n        i += 1\n\n    j = 0\n    t = 0\n    while t <= size_thru:\n        if value['asks'][j][0] == rate_ask:\n            t += value['asks'][j][1] - size_ask\n        else:\n            t += value['asks'][j][1]\n        j += 1\n\n    time.sleep(0.5)\n    return {'bid': value['bids'][i-1][0], 'ask': value['asks'][j-1][0]}\n\n# 自分のポジションを取得する関数 -------------------------------------\ndef getposition():\n\n    while True:\n        try:\n            logger.info('ポジション - 確認')\n            value = bitflyer.private_get_getpositions( params = { \"product_code\" : PAIR })\n            break\n        except Exception as e:\n            logger.info(e)\n            time.sleep(2)\n\n    time.sleep(0.5)\n    return value\n\n# 成行注文する関数 -------------------------------------\ndef market(side, size):\n\n    while True:\n        try:\n            logger.info('成行注文 - 実行')\n            value = bitflyer.create_order(PAIR, type = 'market', side = side, amount = size)\n            break\n        except Exception as e:\n            logger.info(e)\n            time.sleep(2)\n            value = {'id' : 'null'}\n            break\n\n    time.sleep(0.5)\n    return value\n\n# 指値注文する関数 -------------------------------------\ndef limit(side, size, price):\n    while True:\n        try:\n            logger.info('指値注文 - 実行')\n            value = bitflyer.create_order(PAIR, type = 'limit', side = side, amount = size, price = price)\n            break\n        except Exception as e:\n            logger.info(e)\n            time.sleep(1.5)\n            value = {'id' : 'null'}\n            break\n\n    time.sleep(1.5)\n    return value\n\n# 注文をキャンセルする関数 -------------------------------------\ndef cancel(id):\n    try:\n        logger.info('キャンセル - 実行')\n        value = bitflyer.cancelOrder(symbol = PAIR, id = id)\n    except Exception as e:\n        logger.info(e)\n\n        # 指値が約定していた(=キャンセルが通らなかった)場合、\n        # 注文情報を更新(約定済み)して返す\n        value = get_status(id)\n\n    time.sleep(1.5)\n    return value\n\n# 指定した注文idのステータスを参照する関数 -------------------------------------\ndef get_status(id):\n\n    err_cnt = 0\n\n    if PAIR == 'BTC/JPY':\n        PRODUCT = 'BTC_JPY'\n    else:\n        PRODUCT = PAIR\n\n    while True:\n        try:\n            value = bitflyer.private_get_getchildorders(params = {'product_code': PRODUCT, 'child_order_acceptance_id': id})[0]\n            break\n        except Exception as e:\n            logger.info('ステータスが受け取れない為61秒待機。')\n            logger.info(e)\n            time.sleep(61)\n            err_cnt += 1\n            if err_cnt == 5:\n                err_cnt = 0\n                return {'id' : 'null'}\n\n    # APIで受け取った値を読み換える\n    if value['child_order_state'] == 'ACTIVE':\n        status = 'open'\n    elif value['child_order_state'] == 'COMPLETED':\n        status = 'closed'\n    else:\n        status = value['child_order_state']\n\n    # 未約定量を計算する\n    remaining = float(value['size']) - float(value['executed_size'])\n\n    time.sleep(0.1)\n    return {'id': value['child_order_acceptance_id'], 'status': status, 'filled': value['executed_size'], 'remaining': remaining, 'amount': value['size'], 'price': value['price']}\n\n#------------------------------------------------------------------------------#\n\n# 未約定量が存在することを示すフラグ\nremaining_ask_flag = 0\nremaining_bid_flag = 0\n\n#------------------------------------------------------------------------------#\n\nlogger.info('--------TradeStart--------')\nlogger.info('BOT TYPE      : MarketMaker @ bitFlyer')\nlogger.info('SYMBOL        : {0}'.format(PAIR))\nlogger.info('LOT           : {0} {1}'.format(LOT, COIN))\n\n# 残高取得\nTOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])\nlogger.info('--------------------------')\nlogger.info('TOTAL         : {0}'.format(TOTAL))\n\n# 現在の状態tを取得\ntick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)\nask = float(tick['ask'])\nbid = float(tick['bid'])\nspread = (ask - bid) / bid\n\nresult = bitflyer.fetch_ticker(symbol=PAIR)\ntotal_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']\nobservation = ask, bid, spread, total_ask_depth, total_bid_depth, TOTAL\nstate = digitize_state(observation)\n\nprev_change = get_collateralhistory()['change']\ntrade_bid = {}\ntrade_ask = {}\ntrades = []\naction = np.argmax(q_table[state])\nbefore_position = float(get_colla()['open_position_pnl'])\nepisode = 0\ntotal_episode = 0\nreward = 0.0\nepisode_reward = 0\nEARNING = 0\ncontract = 'false'\n\nlong_cnt = 0\nshort_cnt = 0\n\n# 利確設定 \nCONTRACT_PRICE = 100\n\n# 損切設定 \nFAILURE_PRICE = -100\n\nposition_flag = 0\n#------------------------------- メインループ -------------------------------------#\nwhile True:\n\n#------------------------------- エージェントアクション -------------------------------------#\n    # 買い\n    if action == 0:\n        position_flag = 0\n        logger.info('------long-----')\n        trade_bid = market('buy', LOT)\n        trades.append(trade_bid)\n\n    # 売り\n    if action == 1:\n        position_flag = 1\n        logger.info('------short-----')\n        trade_ask = market('sell', LOT)\n        trades.append(trade_ask)\n\n#------------------------------- 報酬 -------------------------------------#\n\n    logger.info('------経過観察中-----')\n    while True:\n        # 実行後の評価損益を記録\n        after_TOTAL = float(get_colla()['collateral']) + float(get_colla()['open_position_pnl'])\n\n        logger.info('--------エージェントの設定値--------')\n        logger.info('実行回数      : {0}'.format(episode))\n        logger.info('ACTION        : {0}'.format(action))\n        logger.info('--------リアルタイム残高--------')\n        logger.info('TOTAL         : {0}'.format(after_TOTAL))\n        \n        # (利確)報酬を記録\n        change = get_collateralhistory()['change']\n        logger.info('利確報酬実行前         : {0}'.format(prev_change))\n        logger.info('利確報酬実行後         : {0}'.format(change))\n        if change != prev_change:\n            prev_change = change\n            reward = change\n            contract = 'true'\n    \n        # (含益)報酬を記録\n        logger.info('含益報酬実行前         : {0}'.format(before_position))\n        logger.info('含益報酬実行後         : {0}'.format(get_colla()['open_position_pnl']))\n        if before_position != float(get_colla()['open_position_pnl']):\n            reward = float(reward) + float(get_colla()['open_position_pnl'])\n            before_position = float(get_colla()['open_position_pnl'])\n    \n        # 総合利益パーセント算出\n        TOTAL_PERCENT = float(after_TOTAL/TOTAL) * 100.0\n    \n        # 収益\n        EARNING = after_TOTAL - TOTAL\n        episode_reward = float(episode_reward) + reward\n    \n        logger.info('--------評価--------')\n        logger.info('REWARD         : {0}'.format(float(reward)))\n        logger.info('TOTAL REWARD   : {0}'.format(float(episode_reward)))\n        logger.info('EARNING        : {:+f}'.format(float(EARNING)))\n        logger.info('TOTAL PERCENT  : {0} %'.format(TOTAL_PERCENT))\n    \n        # 利益+2%または損失-2%に到達したら利確\n        if FAILURE_PRICE >= EARNING or EARNING >= CONTRACT_PRICE:\n            for trade in trades:\n                if 'null' != trade['id']:\n    \n                    if position_flag == 0:\n                        trade = market('sell', LOT)\n                        contract = 'true'\n    \n                    if position_flag == 1:\n                        trade = market('buy', LOT)\n                        contract = 'true'\n    \n            logger.info('------約定完了-----')\n    \n        # 現在の状態tを取得\n        tick = get_effective_tick(size_thru=AMOUNT_THRU, rate_ask=0, size_ask=0, rate_bid=0, size_bid=0)\n        ask = float(tick['ask'])\n        bid = float(tick['bid'])\n        spread = (ask - bid) / bid\n    \n        result = bitflyer.fetch_ticker(symbol=PAIR)\n        total_ask_depth, total_bid_depth = result['info']['total_ask_depth'], result['info']['total_bid_depth']\n        observation = ask, bid, spread, total_ask_depth, total_bid_depth, after_TOTAL\n        state = digitize_state(observation)\n    \n        # メモリに、現在の状態と行った行動、得た報酬を記録する\n        memory.add((state, action, reward))\n    \n        # 約定されたタイミングでテーブル更新\n        if contract == 'true':\n            logger.info('約定確定')\n            q_table = update_Qtable_montecarlo(q_table, memory)\n            action = np.argmax(q_table[state])\n            data = np.array(q_table)\n            np.savetxt(\"q_table.csv\", data, delimiter=',')\n            contract = 'false'\n            break\n\n        else:\n            # 次ステップへ行動と状態を更新\n            next_state = digitize_state(observation)  # t+1での観測状態を、離散値に変換\n            next_action = get_action(next_state, episode)  # 次の行動a_{t+1}を求める\n            action = next_action  # a_{t+1}\n            state = next_state  # s_{t+1}\n    \n        # エピソード記録\n        episode += 1\n        total_episode += 1\n    \n        # 報酬リセット\n        reward = 0\n\n\n\n</code></pre>\n</html>",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"fx\",\"bot\",\"japanese\",\"jp-newbie\"],\"links\":[\"https://note.mu/magimagi1223/n/n5fba7501dcfd\"],\"app\":\"steemit/0.1\",\"format\":\"html\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "2kdc6b-bitcoin-fx",
      "title": "強化学習によるBitcoin FXの攻略 ソースコード公開"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-07T15:36:06",
  "trx_id": "137521c67080de29694b3c9afc29d8add8cf2ad9",
  "trx_in_block": 11,
  "virtual_op": 0
}
2018/09/05 04:35:54
authorspeakyourmind
permlinkpost-on-chainbbcomfspeakyourmind-and-get-a-free-upvote
voterjianty
weight0 (0.00%)
Transaction InfoBlock #25684128/Trx a3bebf66f2b118ee8d43a9a9f7155c5c296d74c3
View Raw JSON Data
{
  "block": 25684128,
  "op": [
    "vote",
    {
      "author": "speakyourmind",
      "permlink": "post-on-chainbbcomfspeakyourmind-and-get-a-free-upvote",
      "voter": "jianty",
      "weight": 0
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-05T04:35:54",
  "trx_id": "a3bebf66f2b118ee8d43a9a9f7155c5c296d74c3",
  "trx_in_block": 12,
  "virtual_op": 0
}
2018/09/05 04:35:36
authorthecyclist
permlinkanother-sick-brumotti-video
voterjianty
weight0 (0.00%)
Transaction InfoBlock #25684122/Trx c7e4b211fd2729b47d8010fd6e4177e1b8f012f7
View Raw JSON Data
{
  "block": 25684122,
  "op": [
    "vote",
    {
      "author": "thecyclist",
      "permlink": "another-sick-brumotti-video",
      "voter": "jianty",
      "weight": 0
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-05T04:35:36",
  "trx_id": "c7e4b211fd2729b47d8010fd6e4177e1b8f012f7",
  "trx_in_block": 1,
  "virtual_op": 0
}
2018/09/05 04:35:15
authoryasu24
permlink2-japanese-steemit-comment-challenge-200sp
voterjianty
weight0 (0.00%)
Transaction InfoBlock #25684115/Trx 49321156dd1e99162b30936e43bd4cde0ebb5565
View Raw JSON Data
{
  "block": 25684115,
  "op": [
    "vote",
    {
      "author": "yasu24",
      "permlink": "2-japanese-steemit-comment-challenge-200sp",
      "voter": "jianty",
      "weight": 0
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-05T04:35:15",
  "trx_id": "49321156dd1e99162b30936e43bd4cde0ebb5565",
  "trx_in_block": 18,
  "virtual_op": 0
}
2018/09/05 04:34:45
authoragorise
permlinkpalmpay-v1-1-4-released-the-point-of-sale-app-that-pays-every-3-seconds-bitcoin-cash-dash-and-monero-added-spark-and-easydex
voterjianty
weight0 (0.00%)
Transaction InfoBlock #25684105/Trx 1382c67d24cc8c46efdd2d4a4c0c57daf38da9e0
View Raw JSON Data
{
  "block": 25684105,
  "op": [
    "vote",
    {
      "author": "agorise",
      "permlink": "palmpay-v1-1-4-released-the-point-of-sale-app-that-pays-every-3-seconds-bitcoin-cash-dash-and-monero-added-spark-and-easydex",
      "voter": "jianty",
      "weight": 0
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-05T04:34:45",
  "trx_id": "1382c67d24cc8c46efdd2d4a4c0c57daf38da9e0",
  "trx_in_block": 7,
  "virtual_op": 0
}
2018/09/05 04:34:06
authorrandomthoughts
permlinkhow-much-bubble-wrap-do-you-need-to-wrap-a-whale-heart
voterjianty
weight0 (0.00%)
Transaction InfoBlock #25684092/Trx c0d60a00549c9ac6d1160abc74adcfa5464efde5
View Raw JSON Data
{
  "block": 25684092,
  "op": [
    "vote",
    {
      "author": "randomthoughts",
      "permlink": "how-much-bubble-wrap-do-you-need-to-wrap-a-whale-heart",
      "voter": "jianty",
      "weight": 0
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-09-05T04:34:06",
  "trx_id": "c0d60a00549c9ac6d1160abc74adcfa5464efde5",
  "trx_in_block": 30,
  "virtual_op": 0
}

Account Metadata

POSTING JSON METADATA
None
JSON METADATA
None
{
  "posting_json_metadata": {},
  "json_metadata": {}
}

Auth Keys

Owner
Single Signature
Public Keys
STM5EfxGGARU26dwpxSKL7XBufNufPjATjarqM1Cn8FAKt4wmGiQx1/1
Active
Single Signature
Public Keys
STM4uM3sGWPkXiTr37ruTaHTHt9tqeFpjwwmjVKcWrs1MSYMvXoEq1/1
Posting
Single Signature
Public Keys
STM5VJ6NkcFHcULd1dcxzxvZaAhEyV2nChuSnQE9GSkEjU5eJXGao1/1
Memo
STM578hgfQqUYyfcX4jKtme7q26Ng6VbCt5aEim1xatC6e2zyJzJB
{
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5EfxGGARU26dwpxSKL7XBufNufPjATjarqM1Cn8FAKt4wmGiQx",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM4uM3sGWPkXiTr37ruTaHTHt9tqeFpjwwmjVKcWrs1MSYMvXoEq",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5VJ6NkcFHcULd1dcxzxvZaAhEyV2nChuSnQE9GSkEjU5eJXGao",
        1
      ]
    ]
  },
  "memo": "STM578hgfQqUYyfcX4jKtme7q26Ng6VbCt5aEim1xatC6e2zyJzJB"
}

Witness Votes

0 / 30
No active witness votes.
[]