diff --git a/sources/tech/20200415 How to automate your cryptocurrency trades with Python.md b/sources/tech/20200415 How to automate your cryptocurrency trades with Python.md
deleted file mode 100644
index 01ae887940..0000000000
--- a/sources/tech/20200415 How to automate your cryptocurrency trades with Python.md
+++ /dev/null
@@ -1,424 +0,0 @@
-[#]: collector: (lujun9972)
-[#]: translator: (wyxplus)
-[#]: reviewer: ( )
-[#]: publisher: ( )
-[#]: url: ( )
-[#]: subject: (How to automate your cryptocurrency trades with Python)
-[#]: via: (https://opensource.com/article/20/4/python-crypto-trading-bot)
-[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
-
-How to automate your cryptocurrency trades with Python
-======
-In this tutorial, learn how to set up and use Pythonic, a graphical
-programming tool that makes it easy for users to create Python
-applications using ready-made function modules.
-![scientific calculator][1]
-
-Unlike traditional stock exchanges like the New York Stock Exchange that have fixed trading hours, cryptocurrencies are traded 24/7, which makes it impossible for anyone to monitor the market on their own.
-
-Often in the past, I had to deal with the following questions related to my crypto trading:
-
- * What happened overnight?
- * Why are there no log entries?
- * Why was this order placed?
- * Why was no order placed?
-
-
-
-The usual solution is to use a crypto trading bot that places orders for you when you are doing other things, like sleeping, being with your family, or enjoying your spare time. There are a lot of commercial solutions available, but I wanted an open source option, so I created the crypto-trading bot [Pythonic][2]. As [I wrote][3] in an introductory article last year, "Pythonic is a graphical programming tool that makes it easy for users to create Python applications using ready-made function modules." It originated as a cryptocurrency bot and has an extensive logging engine and well-tested, reusable parts such as schedulers and timers.
-
-### Getting started
-
-This hands-on tutorial teaches you how to get started with Pythonic for automated trading. It uses the example of trading [Tron][4] against [Bitcoin][5] on the [Binance][6] exchange platform. I choose these coins because of their volatility against each other, rather than any personal preference.
-
-The bot will make decisions based on [exponential moving averages][7] (EMAs).
-
-![TRX/BTC 1-hour candle chart][8]
-
-TRX/BTC 1-hour candle chart
-
-The EMA indicator is, in general, a weighted moving average that gives more weight to recent price data. Although a moving average may be a simple indicator, I've had good experiences using it.
-
-The purple line in the chart above shows an EMA-25 indicator (meaning the last 25 values were taken into account).
-
-The bot monitors the pitch between the current EMA-25 value (t0) and the previous EMA-25 value (t-1). If the pitch exceeds a certain value, it signals rising prices, and the bot will place a buy order. If the pitch falls below a certain value, the bot will place a sell order.
-
-The pitch will be the main indicator for making decisions about trading. For this tutorial, it will be called the _trade factor_.
-
-### Toolchain
-
-The following tools are used in this tutorial:
-
- * Binance expert trading view (visualizing data has been done by many others, so there's no need to reinvent the wheel by doing it yourself)
- * Jupyter Notebook for data-science tasks
- * Pythonic, which is the overall framework
- * PythonicDaemon as the pure runtime (console- and Linux-only)
-
-
-
-### Data mining
-
-For a crypto trading bot to make good decisions, it's essential to get open-high-low-close ([OHLC][9]) data for your asset in a reliable way. You can use Pythonic's built-in elements and extend them with your own logic.
-
-The general workflow is:
-
- 1. Synchronize with Binance time
- 2. Download OHLC data
- 3. Load existing OHLC data from the file into memory
- 4. Compare both datasets and extend the existing dataset with the newer rows
-
-
-
-This workflow may be a bit overkill, but it makes this solution very robust against downtime and disconnections.
-
-To begin, you need the **Binance OHLC Query** element and a **Basic Operation** element to execute your own code.
-
-![Data-mining workflow][10]
-
-Data-mining workflow
-
-The OHLC query is set up to query the asset pair **TRXBTC** (Tron/Bitcoin) in one-hour intervals.
-
-![Configuration of the OHLC query element][11]
-
-Configuring the OHLC query element
-
-The output of this element is a [Pandas DataFrame][12]. You can access the DataFrame with the **input** variable in the **Basic Operation** element. Here, the **Basic Operation** element is set up to use Vim as the default code editor.
-
-![Basic Operation element set up to use Vim][13]
-
-Basic Operation element set up to use Vim
-
-Here is what the code looks like:
-
-
-```
-import pickle, pathlib, os
-import pandas as pd
-
-outout = None
-
-if isinstance(input, pd.DataFrame):
- file_name = 'TRXBTC_1h.bin'
- home_path = str(pathlib.Path.home())
- data_path = os.path.join(home_path, file_name)
-
- try:
- df = pickle.load(open(data_path, 'rb'))
- n_row_cnt = df.shape[0]
- df = pd.concat([df,input], ignore_index=True).drop_duplicates(['close_time'])
- df.reset_index(drop=True, inplace=True)
- n_new_rows = df.shape[0] - n_row_cnt
- log_txt = '{}: {} new rows written'.format(file_name, n_new_rows)
- except:
- log_txt = 'File error - writing new one: {}'.format(e)
- df = input
-
- pickle.dump(df, open(data_path, "wb" ))
- output = df
-```
-
-First, check whether the input is the DataFrame type. Then look inside the user's home directory (**~/**) for a file named **TRXBTC_1h.bin**. If it is present, then open it, concatenate new rows (the code in the **try** section), and drop overlapping duplicates. If the file doesn't exist, trigger an _exception_ and execute the code in the **except** section, creating a new file.
-
-As long as the checkbox **log output** is enabled, you can follow the logging with the command-line tool **tail**:
-
-
-```
-`$ tail -f ~/Pythonic_2020/Feb/log_2020_02_19.txt`
-```
-
-For development purposes, skip the synchronization with Binance time and regular scheduling for now. This will be implemented below.
-
-### Data preparation
-
-The next step is to handle the evaluation logic in a separate grid; therefore, you have to pass over the DataFrame from Grid 1 to the first element of Grid 2 with the help of the **Return element**.
-
-In Grid 2, extend the DataFrame by a column that contains the EMA values by passing the DataFrame through a **Basic Technical Analysis** element.
-
-![Technical analysis workflow in Grid 2][14]
-
-Technical analysis workflow in Grid 2
-
-Configure the technical analysis element to calculate the EMAs over a period of 25 values.
-
-![Configuration of the technical analysis element][15]
-
-Configuring the technical analysis element
-
-When you run the whole setup and activate the debug output of the **Technical Analysis** element, you will realize that the values of the EMA-25 column all seem to be the same.
-
-![Missing decimal places in output][16]
-
-Decimal places are missing in the output
-
-This is because the EMA-25 values in the debug output include just six decimal places, even though the output retains the full precision of an 8-byte float value.
-
-For further processing, add a **Basic Operation** element:
-
-![Workflow in Grid 2][17]
-
-Workflow in Grid 2
-
-With the **Basic Operation** element, dump the DataFrame with the additional EMA-25 column so that it can be loaded into a Jupyter Notebook;
-
-![Dump extended DataFrame to file][18]
-
-Dump extended DataFrame to file
-
-### Evaluation logic
-
-Developing the evaluation logic inside Juypter Notebook enables you to access the code in a more direct way. To load the DataFrame, you need the following lines:
-
-![Representation with all decimal places][19]
-
-Representation with all decimal places
-
-You can access the latest EMA-25 values by using [**iloc**][20] and the column name. This keeps all of the decimal places.
-
-You already know how to get the latest value. The last line of the example above shows only the value. To copy the value to a separate variable, you have to access it with the **.at** method, as shown below.
-
-You can also directly calculate the trade factor, which you will need in the next step.
-
-![Buy/sell decision][21]
-
-Buy/sell decision
-
-### Determine the trading factor
-
-As you can see in the code above, I chose 0.009 as the trade factor. But how do I know if 0.009 is a good trading factor for decisions? Actually, this factor is really bad, so instead, you can brute-force the best-performing trade factor.
-
-Assume that you will buy or sell based on the closing price.
-
-![Validation function][22]
-
-Validation function
-
-In this example, **buy_factor** and **sell_factor** are predefined. So extend the logic to brute-force the best performing values.
-
-![Nested for loops for determining the buy and sell factor][23]
-
-Nested _for_ loops for determining the buy and sell factor
-
-This has 81 loops to process (9x9), which takes a couple of minutes on my machine (a Core i7 267QM).
-
-![System utilization while brute forcing][24]
-
-System utilization while brute-forcing
-
-After each loop, it appends a tuple of **buy_factor**, **sell_factor**, and the resulting **profit** to the **trading_factors** list. Sort the list by profit in descending order.
-
-![Sort profit with related trading factors in descending order][25]
-
-Sort profit with related trading factors in descending order
-
-When you print the list, you can see that 0.002 is the most promising factor.
-
-![Sorted list of trading factors and profit][26]
-
-Sorted list of trading factors and profit
-
-When I wrote this in March 2020, the prices were not volatile enough to present more promising results. I got much better results in February, but even then, the best-performing trading factors were also around 0.002.
-
-### Split the execution path
-
-Start a new grid now to maintain clarity. Pass the DataFrame with the EMA-25 column from Grid 2 to element 0A of Grid 3 by using a **Return** element.
-
-In Grid 3, add a **Basic Operation** element to execute the evaluation logic. Here is the code of that element:
-
-![Implemented evaluation logic][27]
-
-Implemented evaluation logic
-
-The element outputs a **1** if you should buy or a **-1** if you should sell. An output of **0** means there's nothing to do right now. Use a **Branch** element to control the execution path.
-
-![Branch element: Grid 3 Position 2A][28]
-
-Branch element: Grid 3, Position 2A
-
-Due to the fact that both **0** and **-1** are processed the same way, you need an additional Branch element on the right-most execution path to decide whether or not you should sell.
-
-![Branch element: Grid 3 Position 3B][29]
-
-Branch element: Grid 3, Position 3B
-
-Grid 3 should now look like this:
-
-![Workflow on Grid 3][30]
-
-Workflow on Grid 3
-
-### Execute orders
-
-Since you cannot buy twice, you must keep a persistent variable between the cycles that indicates whether you have already bought.
-
-You can do this with a **Stack element**. The Stack element is, as the name suggests, a representation of a file-based stack that can be filled with any Python data type.
-
-You need to define that the stack contains only one Boolean element, which determines if you bought (**True**) or not (**False**). As a consequence, you have to preset the stack with one **False**. You can set this up, for example, in Grid 4 by simply passing a **False** to the stack.
-
-![Forward a False-variable to the subsequent Stack element][31]
-
-Forward a **False** variable to the subsequent Stack element
-
-The Stack instances after the branch tree can be configured as follows:
-
-![Configuration of the Stack element][32]
-
-Configuring the Stack element
-
-In the Stack element configuration, set **Do this with input** to **Nothing**. Otherwise, the Boolean value will be overwritten by a 1 or 0.
-
-This configuration ensures that only one value is ever saved in the stack (**True** or **False**), and only one value can ever be read (for clarity).
-
-Right after the Stack element, you need an additional **Branch** element to evaluate the stack value before you place the **Binance Order** elements.
-
-![Evaluate the variable from the stack][33]
-
-Evaluating the variable from the stack
-
-Append the Binance Order element to the **True** path of the Branch element. The workflow on Grid 3 should now look like this:
-
-![Workflow on Grid 3][34]
-
-Workflow on Grid 3
-
-The Binance Order element is configured as follows:
-
-![Configuration of the Binance Order element][35]
-
-Configuring the Binance Order element
-
-You can generate the API and Secret keys on the Binance website under your account settings.
-
-![Creating an API key in Binance][36]
-
-Creating an API key in the Binance account settings
-
-In this tutorial, every trade is executed as a market trade and has a volume of 10,000 TRX (~US$ 150 on March 2020). (For the purposes of this tutorial, I am demonstrating the overall process by using a Market Order. Because of that, I recommend using at least a Limit order.)
-
-The subsequent element is not triggered if the order was not executed properly (e.g., a connection issue, insufficient funds, or incorrect currency pair). Therefore, you can assume that if the subsequent element is triggered, the order was placed.
-
-Here is an example of output from a successful sell order for XMRBTC:
-
-![Output of a successfully placed sell order][37]
-
-Successful sell order output
-
-This behavior makes subsequent steps more comfortable: You can always assume that as long the output is proper, the order was placed. Therefore, you can append a **Basic Operation** element that simply writes the output to **True** and writes this value on the stack to indicate whether the order was placed or not.
-
-If something went wrong, you can find the details in the logging message (if logging is enabled).
-
-![Logging output of Binance Order element][38]
-
-Logging output from Binance Order element
-
-### Schedule and sync
-
-For regular scheduling and synchronization, prepend the entire workflow in Grid 1 with the **Binance Scheduler** element.
-
-![Binance Scheduler at Grid 1, Position 1A][39]
-
-Binance Scheduler at Grid 1, Position 1A
-
-The Binance Scheduler element executes only once, so split the execution path on the end of Grid 1 and force it to re-synchronize itself by passing the output back to the Binance Scheduler element.
-
-![Grid 1: Split execution path][40]
-
-Grid 1: Split execution path
-
-Element 5A points to Element 1A of Grid 2, and Element 5B points to Element 1A of Grid 1 (Binance Scheduler).
-
-### Deploy
-
-You can run the whole setup 24/7 on your local machine, or you could host it entirely on an inexpensive cloud system. For example, you can use a Linux/FreeBSD cloud system for about US$5 per month, but they usually don't provide a window system. If you want to take advantage of these low-cost clouds, you can use PythonicDaemon, which runs completely inside the terminal.
-
-![PythonicDaemon console interface][41]
-
-PythonicDaemon console
-
-PythonicDaemon is part of the basic installation. To use it, save your complete workflow, transfer it to the remote running system (e.g., by Secure Copy [SCP]), and start PythonicDaemon with the workflow file as an argument:
-
-
-```
-`$ PythonicDaemon trading_bot_one`
-```
-
-To automatically start PythonicDaemon at system startup, you can add an entry to the crontab:
-
-
-```
-`# crontab -e`
-```
-
-![Crontab on Ubuntu Server][42]
-
-Crontab on Ubuntu Server
-
-### Next steps
-
-As I wrote at the beginning, this tutorial is just a starting point into automated trading. Programming trading bots is approximately 10% programming and 90% testing. When it comes to letting your bot trade with your money, you will definitely think thrice about the code you program. So I advise you to keep your code as simple and easy to understand as you can.
-
-If you want to continue developing your trading bot on your own, the next things to set up are:
-
- * Automatic profit calculation (hopefully only positive!)
- * Calculation of the prices you want to buy for
- * Comparison with your order book (i.e., was the order filled completely?)
-
-
-
-You can download the whole example on [GitHub][2].
-
---------------------------------------------------------------------------------
-
-via: https://opensource.com/article/20/4/python-crypto-trading-bot
-
-作者:[Stephan Avenwedde][a]
-选题:[lujun9972][b]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: https://opensource.com/users/hansic99
-[b]: https://github.com/lujun9972
-[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/calculator_money_currency_financial_tool.jpg?itok=2QMa1y8c (scientific calculator)
-[2]: https://github.com/hANSIc99/Pythonic
-[3]: https://opensource.com/article/19/5/graphically-programming-pythonic
-[4]: https://tron.network/
-[5]: https://bitcoin.org/en/
-[6]: https://www.binance.com/
-[7]: https://www.investopedia.com/terms/e/ema.asp
-[8]: https://opensource.com/sites/default/files/uploads/1_ema-25.png (TRX/BTC 1-hour candle chart)
-[9]: https://en.wikipedia.org/wiki/Open-high-low-close_chart
-[10]: https://opensource.com/sites/default/files/uploads/2_data-mining-workflow.png (Data-mining workflow)
-[11]: https://opensource.com/sites/default/files/uploads/3_ohlc-query.png (Configuration of the OHLC query element)
-[12]: https://pandas.pydata.org/pandas-docs/stable/getting_started/dsintro.html#dataframe
-[13]: https://opensource.com/sites/default/files/uploads/4_edit-basic-operation.png (Basic Operation element set up to use Vim)
-[14]: https://opensource.com/sites/default/files/uploads/6_grid2-workflow.png (Technical analysis workflow in Grid 2)
-[15]: https://opensource.com/sites/default/files/uploads/7_technical-analysis-config.png (Configuration of the technical analysis element)
-[16]: https://opensource.com/sites/default/files/uploads/8_missing-decimals.png (Missing decimal places in output)
-[17]: https://opensource.com/sites/default/files/uploads/9_basic-operation-element.png (Workflow in Grid 2)
-[18]: https://opensource.com/sites/default/files/uploads/10_dump-extended-dataframe.png (Dump extended DataFrame to file)
-[19]: https://opensource.com/sites/default/files/uploads/11_load-dataframe-decimals.png (Representation with all decimal places)
-[20]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.iloc.html
-[21]: https://opensource.com/sites/default/files/uploads/12_trade-factor-decision.png (Buy/sell decision)
-[22]: https://opensource.com/sites/default/files/uploads/13_validation-function.png (Validation function)
-[23]: https://opensource.com/sites/default/files/uploads/14_brute-force-tf.png (Nested for loops for determining the buy and sell factor)
-[24]: https://opensource.com/sites/default/files/uploads/15_system-utilization.png (System utilization while brute forcing)
-[25]: https://opensource.com/sites/default/files/uploads/16_sort-profit.png (Sort profit with related trading factors in descending order)
-[26]: https://opensource.com/sites/default/files/uploads/17_sorted-trading-factors.png (Sorted list of trading factors and profit)
-[27]: https://opensource.com/sites/default/files/uploads/18_implemented-evaluation-logic.png (Implemented evaluation logic)
-[28]: https://opensource.com/sites/default/files/uploads/19_output.png (Branch element: Grid 3 Position 2A)
-[29]: https://opensource.com/sites/default/files/uploads/20_editbranch.png (Branch element: Grid 3 Position 3B)
-[30]: https://opensource.com/sites/default/files/uploads/21_grid3-workflow.png (Workflow on Grid 3)
-[31]: https://opensource.com/sites/default/files/uploads/22_pass-false-to-stack.png (Forward a False-variable to the subsequent Stack element)
-[32]: https://opensource.com/sites/default/files/uploads/23_stack-config.png (Configuration of the Stack element)
-[33]: https://opensource.com/sites/default/files/uploads/24_evaluate-stack-value.png (Evaluate the variable from the stack)
-[34]: https://opensource.com/sites/default/files/uploads/25_grid3-workflow.png (Workflow on Grid 3)
-[35]: https://opensource.com/sites/default/files/uploads/26_binance-order.png (Configuration of the Binance Order element)
-[36]: https://opensource.com/sites/default/files/uploads/27_api-key-binance.png (Creating an API key in Binance)
-[37]: https://opensource.com/sites/default/files/uploads/28_sell-order.png (Output of a successfully placed sell order)
-[38]: https://opensource.com/sites/default/files/uploads/29_binance-order-output.png (Logging output of Binance Order element)
-[39]: https://opensource.com/sites/default/files/uploads/30_binance-scheduler.png (Binance Scheduler at Grid 1, Position 1A)
-[40]: https://opensource.com/sites/default/files/uploads/31_split-execution-path.png (Grid 1: Split execution path)
-[41]: https://opensource.com/sites/default/files/uploads/32_pythonic-daemon.png (PythonicDaemon console interface)
-[42]: https://opensource.com/sites/default/files/uploads/33_crontab.png (Crontab on Ubuntu Server)
diff --git a/translated/tech/20200415 How to automate your cryptocurrency trades with Python.md b/translated/tech/20200415 How to automate your cryptocurrency trades with Python.md
new file mode 100644
index 0000000000..85533f8438
--- /dev/null
+++ b/translated/tech/20200415 How to automate your cryptocurrency trades with Python.md
@@ -0,0 +1,429 @@
+[#]: collector: (lujun9972)
+[#]: translator: (wyxplus)
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (How to automate your cryptocurrency trades with Python)
+[#]: via: (https://opensource.com/article/20/4/python-crypto-trading-bot)
+[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
+
+
+如何使用 Python 来自动交易加密货币
+======
+
+在本教程中,教你如何设置和使用 Pythonic 来编程。它是一个图形化编程工具,用户可以很容易地使用现成的函数模块创建 Python 程序。
+
+![scientific calculator][1]
+
+然而,不像纽约证券交易所这样的传统证券交易所一样,有一段固定的交易时间。对于加密货币而言,则是 7×24 小时交易,任何人都无法独自盯着市场。
+
+在以前,我经常思考与加密货币交易相关的问题:
+
+- 一夜之间发生了什么?
+- 为什么没有日志记录?
+- 为什么下单?
+- 为什么不下单?
+
+通常的解决手段是当在你做其他事情时,例如睡觉、与家人在一起或享受空闲时光,使用加密交易机器人代替你下单。虽然有很多商业解决方案可用,但是我选择开源的解决方案,因此我编写了加密交易机器人 [Pythonic][2]。 正如去年 [我写过的文章][3] 一样,“ Pythonic 是一种图形化编程工具,它让用户可以轻松使用现成的功能模块来创建Python应用程序。” 最初它是作为加密货币机器人使用,并具有可扩展的日志记录引擎以及经过精心测试的可重用部件,例如调度器和计时器。
+
+### 开始
+
+本教程将教你如何开始使用 Pythonic 进行自动交易。我选择 [币安][6]Binance[币安][6] 交易所的 [波场][4]Tron[波场][4] 与 [比特币][3]Bitcoin[比特币][3]
+
+交易对为例。我之所以选择这些加密货币,是因为它们彼此之间的波动性大,而不是出于个人喜好。
+
+机器人将根据 [指数移动平均][7] (EMAs)来做出决策。
+
+![TRX/BTC 1-hour candle chart][8]
+
+TRX/BTC 1 小时 K 线图
+
+EMA 指标通常是指加权移动平均线,可以对近期价格数据赋予更多权重。尽管移动平均线可能只是一个简单的指标,但我能熟练使用它。
+
+上图中的紫色线显示了 EMA-25 指标(这表示要考虑最近的 25 个值)。
+
+机器人监视当前的 EMA-25 值(t0)和前一个 EMA-25 值(t-1)之间的差距。如果差值超过某个值,则表示价格上涨,机器人将下达购买订单。如果差值低于某个值,则机器人将下达卖单。
+
+差值将是做出交易决策的主要指标。在本教程中,它称为交易参数。
+
+### 工具链
+
+
+
+将在本教程使用如下工具:
+
+- 币安专业交易视图(已经有其他人做了数据可视化,所以不需要重复造轮子)
+- Jupyter Notebook:用于数据科学任务
+- Pythonic:作为整体框架
+- PythonicDaemon :作为终端运行(仅适用于控制台和 Linux)
+
+
+
+### 数据挖掘
+
+为了使加密货币交易机器人尽可能能做出正确的决定,以可靠的方式获取资产的美国线([OHLC][9])数据是至关重要。你可以使用 Pythonic 的内置元素,还可以根据自己逻辑来对其进行扩展。
+
+一般的工作流程:
+
+1. 与币安时间同步
+2. 下载 OHLC 数据
+3. 从文件中把 OHLC 数据加载到内存
+4. 比较数据集并扩展更新数据集
+
+
+
+这个工作流程可能有点夸张,但是它能使得程序更加健壮,甚至在停机和断开连接时,也能平稳运行。
+
+一开始,你需要 **币安 OHLC 查询**Binance OHLC Query**币安 OHLC 查询** 元素和一个 **基础操作**Basic Operation**基础操作** 元素来执行你的代码。
+
+![Data-mining workflow][10]
+
+数据挖掘工作流程
+
+OHLC 查询设置为每隔一小时查询一次 **TRXBTC** 资产对(波场/比特币)。
+
+![Configuration of the OHLC query element][11]
+
+配置 OHLC 查询元素
+
+其中输出的元素是 [Pandas DataFrame][12]。你可以在 **基础操作** 元素中使用 **输入**input**输入** 变量来访问 DataFrame。其中,将 Vim 设置为 **基础操作** 元素的默认代码编辑器。
+
+![Basic Operation element set up to use Vim][13]
+
+使用 Vim 编辑基础操作元素
+
+具体代码如下:
+
+
+```
+import pickle, pathlib, os
+import pandas as pd
+
+outout = None
+
+if isinstance(input, pd.DataFrame):
+ file_name = 'TRXBTC_1h.bin'
+ home_path = str(pathlib.Path.home())
+ data_path = os.path.join(home_path, file_name)
+
+ try:
+ df = pickle.load(open(data_path, 'rb'))
+ n_row_cnt = df.shape[0]
+ df = pd.concat([df,input], ignore_index=True).drop_duplicates(['close_time'])
+ df.reset_index(drop=True, inplace=True)
+ n_new_rows = df.shape[0] - n_row_cnt
+ log_txt = '{}: {} new rows written'.format(file_name, n_new_rows)
+ except:
+ log_txt = 'File error - writing new one: {}'.format(e)
+ df = input
+
+ pickle.dump(df, open(data_path, "wb" ))
+ output = df
+```
+
+首先,检查输入是否为 DataFrame 元素。然后在用户的家目录(**〜/ **)中查找名为 **TRXBTC_1h.bin** 的文件。如果存在,则将其打开,执行新代码段(**try** 部分中的代码),并删除重复项。如果文件不存在,则触发异常并执行 **except** 部分中的代码,创建一个新文件。
+
+只要启用了复选框 **日志输出**log output**日志输出**,你就可以使用命令行工具 **tail** 查看日志记录:
+
+
+```
+`$ tail -f ~/Pythonic_2020/Feb/log_2020_02_19.txt`
+```
+
+出于开发目的,现在跳过与币安时间的同步和计划执行,这将在下面实现。
+
+### 准备数据
+
+下一步是在单独的 网格Grid网格 中处理评估逻辑。因此,你必须借助 **返回元素**Return element**返回元素** 将 DataFrame 从网格 1 传递到网格 2 的第一个元素。
+
+在网格 2 中,通过使 DataFrame 通过 **基础技术分析**Basic Technical Analysis**基础技术分析** 元素,将 DataFrame 扩展包含 EMA 值的一列。
+
+![Technical analysis workflow in Grid 2][14]
+
+在网格 2 中技术分析工作流程
+
+配置技术分析元素以计算 25 个值的 EMAs。
+
+![Configuration of the technical analysis element][15]
+
+配置技术分析元素
+
+当你运行整个程序并开启 **技术分析**Technical Analysis**技术分析** 元素的调试输出时,你将发现 EMA-25 列的值似乎都相同。
+
+![Missing decimal places in output][16]
+
+输出中精度不够
+
+这是因为调试输出中的 EMA-25 值仅包含六位小数,即使输出保留了 8 个字节完整精度的浮点值。
+
+为了能进行进一步处理,请添加 **基础操作** 元素:
+
+![Workflow in Grid 2][17]
+
+网格 2 中的工作流程
+
+使用 **基础操作** 元素,将 DataFrame 与添加的 EMA-25 列一起转储,以便可以将其加载到 Jupyter Notebook中;
+
+![Dump extended DataFrame to file][18]
+
+将扩展后的 DataFrame 存储到文件中
+
+### 评估策略
+
+在 Juypter Notebook 中开发评估策略,让你可以更直接地访问代码。要加载 DataFrame,你需要使用如下代码:
+
+![Representation with all decimal places][19]
+
+用全部小数位表示
+
+你可以使用 [**iloc**][20] 和列名来访问最新的 EMA-25 值,并且会保留所有小数位。
+
+你已经知道如何来获得最新的数据。上面示例的最后一行仅显示该值。为了能将该值拷贝到不同的变量中,你必须使用如下图所示的 **.at** 方法方能成功。
+
+你也可以直接计算出你下一步所需的交易参数。
+
+![Buy/sell decision][21]
+
+买卖决策
+
+### 确定交易参数
+
+如上面代码所示,我选择 0.009 作为交易参数。但是我怎么知道 0.009 是决定交易的一个好参数呢? 实际上,这个参数确实很糟糕,因此,你可以直接计算出表现最佳的交易参数。
+
+假设你将根据收盘价进行买卖。
+
+![Validation function][22]
+
+回测功能
+
+在此示例中,**buy_factor** 和 **sell_factor** 是预先定义好的。因此,发散思维用直接计算出表现最佳的参数。
+
+![Nested for loops for determining the buy and sell factor][23]
+
+嵌套的 _for_ 循环,用于确定购买和出售的参数
+
+这要跑 81 个循环(9x9),在我的机器(Core i7 267QM)上花费了几分钟。
+
+![System utilization while brute forcing][24]
+
+在暴力运算时系统的利用率
+
+在每个循环之后,它将 **buy_factor**,**sell_factor** 元组和生成的 **利润**profit**利润** 元组追加到 **trading_factors** 列表中。按利润降序对列表进行排序。
+
+![Sort profit with related trading factors in descending order][25]
+
+将利润与相关的交易参数按降序排序
+
+当你打印出列表时,你会看到 0.002 是最好的参数。
+
+![Sorted list of trading factors and profit][26]
+
+交易要素和收益的有序列表
+
+当我在 2020 年 3 月写下这篇文章时,价格的波动还不足以呈现出更理想的结果。我在 2 月份得到了更好的结果,但即使在那个时候,表现最好的交易参数也在 0.002 左右。
+
+### 分割执行路径
+
+现在开始新建一个网格以保持逻辑清晰。使用 **返回** 元素将带有 EMA-25 列的 DataFrame 从网格 2 传递到网格 3 的 0A 元素。
+
+在网格 3 中,添加 **基础操作** 元素以执行评估逻辑。这是该元素中的代码:
+
+![Implemented evaluation logic][27]
+
+实现评估策略
+
+如果输出 **1** 表示你应该购买,如果输出 **2** 则表示你应该卖出。 输出 **0** 表示现在无需操作。使用 **分支**Branch**分支** 元素来控制执行路径。
+
+![Branch element: Grid 3 Position 2A][28]
+
+Branch 元素:网格 3,2A 位置
+
+
+
+因为 **0** 和 **-1** 的处理流程一样,所以你需要在最右边添加一个分支元素来判断你是否应该卖出。
+
+![Branch element: Grid 3 Position 3B][29]
+
+分支元素:网格 3,3B 位置
+
+网格 3 应该现在如下图所示:
+
+![Workflow on Grid 3][30]
+
+网格 3 的工作流程
+
+### 下单
+
+由于无需在一个周期中购买两次,因此必须在周期之间保留一个持久变量,以指示你是否已经购买。
+
+你可以利用 **栈**Stack**栈** 元素来实现。顾名思义,栈元素表示可以用任何 Python 数据类型来放入的基于文件的栈。
+
+你需要定义栈仅包含一个布尔类型,该布尔类型决定是否购买了(**True**)或(**False**)。因此,你必须使用 **False** 来初始化栈。例如,你可以在网格 4 中简单地通过将 **False** 传递给栈来进行设置。![Forward a False-variable to the subsequent Stack element][31]
+
+将 **False** 变量传输到后续的栈元素中
+
+在分支树后的栈实例可以进行如下配置:
+
+![Configuration of the Stack element][32]
+
+设置栈元素
+
+在栈元素设置中,将 **Do this with input** 设置成 **Nothing**。否则,布尔值将被 1 或 0 覆盖。
+
+该设置确保仅将一个值保存于栈中(**True** 或 **False**),并且只能读取一个值(为了清楚起见)。
+
+在栈元素之后,你需要另外一个 **分支** 元素来判断栈的值,然后再放置 **币安订单**Binance Order**币安订单** 元素。
+
+![Evaluate the variable from the stack][33]
+
+判断栈中的变量
+
+将币安订单元素添加到分支元素的 **True** 路径。网格 3 上的工作流现在应如下所示:
+
+![Workflow on Grid 3][34]
+
+网格 3 的工作流程
+
+币安订单元素应如下配置:
+
+![Configuration of the Binance Order element][35]
+
+编辑币安订单元素
+
+你可以在币安网站上的帐户设置中生成 API 和密钥。
+
+![Creating an API key in Binance][36]
+
+在币安账户设置中创建一个 API key
+
+在本文中,每笔交易都是作为市价交易执行的,交易量为10,000 TRX(2020 年 3 月约为 150 美元)(出于教学的目的,我通过使用市价下单来演示整个过程。因此,我建议至少使用限价下单。)
+
+如果未正确执行下单(例如,网络问题、资金不足或货币对不正确),则不会触发后续元素。因此,你可以假定如果触发了后续元素,则表示该订单已下达。
+
+这是一个成功的 XMRBTC 卖单的输出示例:
+
+![Output of a successfully placed sell order][37]
+
+成功卖单的输出
+
+该行为使后续步骤更加简单:你可以始终假设只要成功输出,就表示订单成功。因此,你可以添加一个 **基础操作** 元素,该元素将简单地输出 **True** 并将此值放入栈中以表示是否下单。
+
+如果出现错误的话,你可以在日志信息中查看具体细节(如果启用日志功能)。
+
+![Logging output of Binance Order element][38]
+
+币安订单元素中的输出日志信息
+
+### 调度和同步
+
+对于日程调度和同步,请在网格 1 中将整个工作流程置于 **币安调度器**Binance Scheduler**币安调度器** 元素的前面。
+
+![Binance Scheduler at Grid 1, Position 1A][39]
+
+在网格 1,1A 位置的币安调度器
+
+由于币安调度器元素只执行一次,因此请在网格 1 的末尾拆分执行路径,并通过将输出传递回币安调度器来强制让其重新同步。
+
+![Grid 1: Split execution path][40]
+
+网格 1:拆分执行路径
+
+5A 元素指向 网格 2 的 1A 元素,并且 5B 元素指向网格 1 的 1A 元素(币安调度器)。
+
+### 部署
+
+你可以在本地计算机上全天候 7×24 小时运行整个程序,也可以将其完全托管在廉价的云系统上。例如,你可以使用 Linux/FreeBSD 云系统,每月约 5 美元,但通常不提供图形化界面。如果你想利用这些低成本的云,可以使用 PythonicDaemon,它能在终端中完全运行。
+
+![PythonicDaemon console interface][41]
+
+PythonicDaemon 控制台
+
+PythonicDaemon 是基础程序的一部分。要使用它,请保存完整的工作流程,将其传输到远程运行的系统中(例如,通过安全拷贝协议Secure Copy安全拷贝协议 [SCP]),然后把工作流程文件作为参数来启动 PythonicDaemon:
+
+
+```
+`$ PythonicDaemon trading_bot_one`
+```
+
+为了能在系统启动时自启 PythonicDaemon,可以将一个条目添加到 crontab 中:
+
+
+```
+`# crontab -e`
+```
+
+![Crontab on Ubuntu Server][42]
+
+在 Ubuntu 服务器上的 Crontab
+
+### 下一步
+
+正如我在一开始时所说的,本教程只是自动交易的入门。对交易机器人进行编程大约需要 10% 的编程和 90% 的测试。当涉及到让你的机器人用金钱交易时,你肯定会对编写的代码再三思考。因此,我建议你编码时要尽可能简单和易于理解。
+
+
+
+如果你想自己继续开发交易机器人,接下来所需要做的事:
+
+- 收益自动计算(希望你有正收益!)
+- 计算你想买的价格
+- 比较你的预订单(例如,订单是否填写完整?)
+
+
+
+你可以从 [GitHub][2] 上获取完整代码。
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/article/20/4/python-crypto-trading-bot
+
+作者:[Stephan Avenwedde][a]
+选题:[lujun9972][b]
+译者:[wyxplus](https://github.com/wyxplus)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://opensource.com/users/hansic99
+[b]: https://github.com/lujun9972
+[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/calculator_money_currency_financial_tool.jpg?itok=2QMa1y8c "scientific calculator"
+[2]: https://github.com/hANSIc99/Pythonic
+[3]: https://opensource.com/article/19/5/graphically-programming-pythonic
+[4]: https://tron.network/
+[5]: https://bitcoin.org/en/
+[6]: https://www.binance.com/
+[7]: https://www.investopedia.com/terms/e/ema.asp
+[8]: https://opensource.com/sites/default/files/uploads/1_ema-25.png "TRX/BTC 1-hour candle chart"
+[9]: https://en.wikipedia.org/wiki/Open-high-low-close_chart
+[10]: https://opensource.com/sites/default/files/uploads/2_data-mining-workflow.png "Data-mining workflow"
+[11]: https://opensource.com/sites/default/files/uploads/3_ohlc-query.png "Configuration of the OHLC query element"
+[12]: https://pandas.pydata.org/pandas-docs/stable/getting_started/dsintro.html#dataframe
+[13]: https://opensource.com/sites/default/files/uploads/4_edit-basic-operation.png "Basic Operation element set up to use Vim"
+[14]: https://opensource.com/sites/default/files/uploads/6_grid2-workflow.png "Technical analysis workflow in Grid 2"
+[15]: https://opensource.com/sites/default/files/uploads/7_technical-analysis-config.png "Configuration of the technical analysis element"
+[16]: https://opensource.com/sites/default/files/uploads/8_missing-decimals.png "Missing decimal places in output"
+[17]: https://opensource.com/sites/default/files/uploads/9_basic-operation-element.png "Workflow in Grid 2"
+[18]: https://opensource.com/sites/default/files/uploads/10_dump-extended-dataframe.png "Dump extended DataFrame to file"
+[19]: https://opensource.com/sites/default/files/uploads/11_load-dataframe-decimals.png "Representation with all decimal places"
+[20]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.iloc.html
+[21]: https://opensource.com/sites/default/files/uploads/12_trade-factor-decision.png "Buy/sell decision"
+[22]: https://opensource.com/sites/default/files/uploads/13_validation-function.png "Validation function"
+[23]: https://opensource.com/sites/default/files/uploads/14_brute-force-tf.png "Nested for loops for determining the buy and sell factor"
+[24]: https://opensource.com/sites/default/files/uploads/15_system-utilization.png "System utilization while brute forcing"
+[25]: https://opensource.com/sites/default/files/uploads/16_sort-profit.png "Sort profit with related trading factors in descending order"
+[26]: https://opensource.com/sites/default/files/uploads/17_sorted-trading-factors.png "Sorted list of trading factors and profit"
+[27]: https://opensource.com/sites/default/files/uploads/18_implemented-evaluation-logic.png "Implemented evaluation logic"
+[28]: https://opensource.com/sites/default/files/uploads/19_output.png "Branch element: Grid 3 Position 2A"
+[29]: https://opensource.com/sites/default/files/uploads/20_editbranch.png "Branch element: Grid 3 Position 3B"
+[30]: https://opensource.com/sites/default/files/uploads/21_grid3-workflow.png "Workflow on Grid 3"
+[31]: https://opensource.com/sites/default/files/uploads/22_pass-false-to-stack.png "Forward a False-variable to the subsequent Stack element"
+[32]: https://opensource.com/sites/default/files/uploads/23_stack-config.png "Configuration of the Stack element"
+[33]: https://opensource.com/sites/default/files/uploads/24_evaluate-stack-value.png "Evaluate the variable from the stack"
+[34]: https://opensource.com/sites/default/files/uploads/25_grid3-workflow.png "Workflow on Grid 3"
+[35]: https://opensource.com/sites/default/files/uploads/26_binance-order.png "Configuration of the Binance Order element"
+[36]: https://opensource.com/sites/default/files/uploads/27_api-key-binance.png "Creating an API key in Binance"
+[37]: https://opensource.com/sites/default/files/uploads/28_sell-order.png "Output of a successfully placed sell order"
+[38]: https://opensource.com/sites/default/files/uploads/29_binance-order-output.png "Logging output of Binance Order element"
+[39]: https://opensource.com/sites/default/files/uploads/30_binance-scheduler.png "Binance Scheduler at Grid 1, Position 1A"
+[40]: https://opensource.com/sites/default/files/uploads/31_split-execution-path.png "Grid 1: Split execution path"
+[41]: https://opensource.com/sites/default/files/uploads/32_pythonic-daemon.png "PythonicDaemon console interface"
+[42]: https://opensource.com/sites/default/files/uploads/33_crontab.png "Crontab on Ubuntu Server"