Unlike traditional stock exchanges such as the New York Stock Exchange, which operate during fixed trading hours, cryptocurrency markets run 24/7. This constant activity makes it impossible for anyone to monitor the markets manually at all times.
Many traders face common questions:
- What happened overnight?
- Why was an order placed—or not placed?
- How can I maintain a reliable log of trading activity?
The typical solution is to use a crypto trading bot that executes trades on your behalf while you sleep, spend time with family, or enjoy leisure activities. While numerous commercial options exist, this guide focuses on an open-source approach using a tool called Pythonic.
Getting Started with Automated Trading
Pythonic is a graphical programming tool that enables users to build Python applications easily using ready-made function modules. Originally designed as a cryptocurrency trading bot, it includes an extensible logging engine and well-tested reusable components like schedulers and timers.
This tutorial will guide you through setting up an automated trading strategy using Pythonic. We’ll use the Tron (TRX) and Bitcoin (BTC) trading pair on the Binance exchange as an example—selected for its high volatility rather than personal preference.
The bot will make decisions based on Exponential Moving Averages (EMA), a weighted moving average that assigns greater importance to recent price data. Though simple, EMAs are effective and widely used.
The Core Strategy
The bot monitors the gap between the current EMA-25 value (t₀) and the previous one (t₋₁). If the difference exceeds a certain threshold, it signals a price increase, and the bot places a buy order. If the difference falls below a specific value, the bot places a sell order. This difference, referred to as the trading parameter, drives the decision-making process.
Toolchain
We’ll use the following tools:
- Binance Pro Trading View: For data visualization (no need to reinvent the wheel)
- Jupyter Notebook: For data science tasks and strategy development
- Pythonic: As the main automation framework
- PythonicDaemon: For running the bot in the terminal (Linux/console-only environments)
Data Mining and Management
Reliable data is the foundation of any trading bot. We need to fetch Open-High-Low-Close (OHLC) data for our chosen asset pair robustly, even during downtime or disconnections.
The general workflow:
- Synchronize with Binance server time
- Download OHLC data
- Load existing OHLC data from a local file
- Compare and update the dataset with new data
This approach ensures resilience and continuity.
Fetching Data with Pythonic
Start by using the Binance OHLC Query element paired with a Basic Operation element to execute custom code.
The OHLC query is configured to fetch TRXBTC data at 1-hour intervals. The output is a Pandas DataFrame, which you can access via the input variable in the Basic Operation element.
Here’s a sample code snippet for the Basic Operation element:
import pickle, pathlib, os
import pandas as pd
output = 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 Exception as e:
log_txt = 'File error - writing new one: {}'.format(e)
df = input
pickle.dump(df, open(data_path, "wb"))
output = dfThis code checks if the input is a DataFrame, then looks for a local file TRXBTC_1h.bin in the user’s home directory. If the file exists, it appends new data and removes duplicates; if not, it creates a new file.
Log output can be monitored using:
tail -f ~/Pythonic_2020/Feb/log_2020_02_19.txtData Preparation and Technical Analysis
Pass the DataFrame from Grid 1 to Grid 2 using a Return Element. In Grid 2, use the Basic Technical Analysis element to add an EMA-25 column to the DataFrame.
Configure the technical analysis element to calculate the 25-period EMA. Although the debug output may show rounded values, the actual data retains full floating-point precision.
Dump the extended DataFrame to a file using another Basic Operation element so you can load it into a Jupyter Notebook for further analysis.
Strategy Evaluation and Backtesting
In Jupyter Notebook, develop and test your evaluation strategy. Load the DataFrame and access the latest EMA-25 values using .iloc and .at methods.
Define a validation function to simulate trades based on your strategy. For example:
def validate(buy_factor, sell_factor):
# Simulation logic here
return profitUse nested loops to brute-force the best buy_factor and sell_factor:
trading_factors = []
for buy_factor in [0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009]:
for sell_factor in [0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009]:
profit = validate(buy_factor, sell_factor)
trading_factors.append((buy_factor, sell_factor, profit))
# Sort by profit descending
trading_factors.sort(key=lambda x: x[2], reverse=True)Print the sorted list to identify the most profitable parameters.
Execution Paths and Order Placement
Create a new grid (Grid 3) to keep the logic clean. Use a Basic Operation element to implement the evaluation logic:
output = 0 # Default: no action
ema_gap = df.at[df.shape[0] - 1, 'EMA_25'] - df.at[df.shape[0] - 2, 'EMA_25']
if ema_gap > 0.002: # Buy signal
output = 1
elif ema_gap < -0.002: # Sell signal
output = 2Use a Branch Element to direct the flow based on the output. Since the same action may be taken for multiple outputs (e.g., 0 and -1), structure your branches accordingly.
Managing State with a Stack
Use a Stack Element to persist state between cycles—specifically, whether you’ve already bought in the current cycle. Initialize the stack with False.
Configure the stack to “Do nothing” with the input to avoid overwriting the boolean value. After the stack, add another branch element to evaluate its value and route to the Binance Order element if necessary.
Placing Orders on Binance
Configure the Binance Order element with your API key and secret (generated in your Binance account settings). Execute market orders for 10,000 TRX (adjust based on your capital and risk tolerance).
Note: Market orders are used here for simplicity; consider using limit orders in live trading for better control.
If an order fails (e.g., due to network issues or insufficient funds), subsequent elements won’t trigger. A successful order will output details like order ID and status.
After placing an order, use a Basic Operation element to output True and update the stack to reflect the new state.
Scheduling and Synchronization
Place the entire workflow behind a Binance Scheduler element in Grid 1. Since the scheduler runs only once, split the execution path at the end of Grid 1 and feed back into the scheduler to force resynchronization.
Deployment
Run the bot locally or deploy it to a low-cost cloud server (e.g., a $5/month Linux instance). Use PythonicDaemon for headless operation:
PythonicDaemon trading_bot_oneAdd to crontab for auto-start on boot:
crontab -eAdd the line:
@reboot PythonicDaemon trading_bot_oneNext Steps and Enhancements
Programming a trading bot is about 10% coding and 90% testing. Always prioritize simplicity and clarity when dealing with financial algorithms.
Consider adding:
- Automated profit/loss calculation
- Price prediction for limit orders
- Order book analysis for better entry/exit points
- Explore more strategies to enhance your bot’s capabilities
Frequently Asked Questions
What is an exponential moving average (EMA)?
An EMA is a type of moving average that places greater weight on recent data points. It reacts more quickly to price changes than a simple moving average (SMA), making it popular among traders for identifying trends and generating signals.
Why use Python for automated trading?
Python offers extensive libraries for data analysis, machine learning, and web connectivity. Its simplicity and readability make it ideal for prototyping and deploying trading strategies quickly. Many exchanges also provide Python SDKs for easy integration.
How much capital do I need to start?
This depends on the exchange and trading pair. Some platforms allow trading with as little as $10, but it’s advisable to start with a small amount you’re comfortable risking while testing and refining your strategy.
Can I run this bot on a Raspberry Pi?
Yes, Pythonic and PythonicDaemon can run on ARM-based devices like Raspberry Pi, provided you install the necessary dependencies. Ensure stable internet connectivity and consider the device’s limitations for intensive computations.
How do I secure my API keys?
Never hardcode API keys in your scripts. Use environment variables or secure configuration files with restricted permissions. Most cloud platforms offer secret management services for added security.
What are the risks of automated trading?
Automated trading carries risks including technical failures, network latency, and unexpected market conditions. Always monitor your bot initially, set stop-losses, and never invest more than you can afford to lose. View real-time tools to help manage these risks.