<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Algorithmic Trading Archives - relataly.com</title>
	<atom:link href="https://www.relataly.com/tag/algorithmic-trading/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.relataly.com/tag/algorithmic-trading/</link>
	<description>The Business AI Blog</description>
	<lastBuildDate>Sat, 27 May 2023 10:17:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.relataly.com/wp-content/uploads/2023/04/cropped-AI-cat-Icon-White.png</url>
	<title>Algorithmic Trading Archives - relataly.com</title>
	<link>https://www.relataly.com/tag/algorithmic-trading/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">175977316</site>	<item>
		<title>Automate Crypto Trading with a Python-Powered Twitter Bot and Gate.io Signals</title>
		<link>https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/</link>
					<comments>https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/#comments</comments>
		
		<dc:creator><![CDATA[Florian Follonier]]></dc:creator>
		<pubDate>Wed, 19 May 2021 04:57:00 +0000</pubDate>
				<category><![CDATA[Algorithmic Trading]]></category>
		<category><![CDATA[Finance]]></category>
		<category><![CDATA[Gate.io API]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Stock Market Forecasting]]></category>
		<category><![CDATA[Time Series Forecasting]]></category>
		<category><![CDATA[Twitter API]]></category>
		<category><![CDATA[AI in E-Commerce]]></category>
		<category><![CDATA[API Tutorials]]></category>
		<category><![CDATA[Automated Twitter Posts]]></category>
		<category><![CDATA[Intermediate Tutorials]]></category>
		<category><![CDATA[Social Media Data]]></category>
		<category><![CDATA[Trading Signals]]></category>
		<category><![CDATA[Twitter Bots]]></category>
		<guid isPermaLink="false">https://www.relataly.com/?p=3974</guid>

					<description><![CDATA[<p>This tutorial develops a Twitter bot in Python that will generate automated trading signals. The bot will pull real-time price data on various cryptocurrencies (Bitcoin, Ethereum, Doge, etc.) from the crypto exchange Gate.io and analyze it using predefined rules. Whenever the bot detects a relevant price change, it automatically posts a tweet via Twitter. Simple ... <a title="Automate Crypto Trading with a Python-Powered Twitter Bot and Gate.io Signals" class="read-more" href="https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/" aria-label="Read more about Automate Crypto Trading with a Python-Powered Twitter Bot and Gate.io Signals">Read more</a></p>
<p>The post <a href="https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/">Automate Crypto Trading with a Python-Powered Twitter Bot and Gate.io Signals</a> appeared first on <a href="https://www.relataly.com">relataly.com</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>This tutorial develops a Twitter bot in Python that will generate automated trading signals. The bot will pull real-time price data on various cryptocurrencies (Bitcoin, Ethereum, Doge, etc.) from the <a href="http://www.gate.io/" target="_blank" rel="noreferrer noopener">crypto exchange</a> <em>Gate.io</em> and analyze it using predefined rules. Whenever the bot detects a relevant price change, it automatically posts a tweet via Twitter. Simple Twitter bots can proactively inform their audiences about relevant events in the market. Such an event can be a sharp rise or fall in price or a sudden spike in the trading volume. If we examine data for specific price movements, we can also store these events and use them later to train a predictive model.</p>



<p>More advanced signal bots use predictive models to signal when it is appropriate to enter or exit the market. Or the bot executes the buy- and sell-orders directly itself. A well-defined signaling logic can therefore constitute the first step toward algorithmic trading. But one thing at a time. So in this article, we will begin by developing a simple signal bot.</p>



<p>The rest of this article is structured as follows. First, we take a look at the different code modules of the Twitter bot. After that, we&#8217;ll implement the other code modules in Python. Finally, we will integrate the modules and run some tests. We will also quickly introduce the APIs used to build the bot.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="748" height="506" data-attachment-id="12463" data-permalink="https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/trading-bot-machine-learning-tutorial-gateio-trading-signals-python-min/#main" data-orig-file="https://www.relataly.com/wp-content/uploads/2023/02/trading-bot-machine-learning-tutorial-gateio-trading-signals-python-min.png" data-orig-size="748,506" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="trading-bot-machine-learning-tutorial-gateio-trading-signals-python-min" data-image-description="" data-image-caption="" data-large-file="https://www.relataly.com/wp-content/uploads/2023/02/trading-bot-machine-learning-tutorial-gateio-trading-signals-python-min.png" src="https://www.relataly.com/wp-content/uploads/2023/02/trading-bot-machine-learning-tutorial-gateio-trading-signals-python-min.png" alt="trading bot machine learning tutorial gateio trading signals python. Midjourney. relataly.com" class="wp-image-12463" srcset="https://www.relataly.com/wp-content/uploads/2023/02/trading-bot-machine-learning-tutorial-gateio-trading-signals-python-min.png 748w, https://www.relataly.com/wp-content/uploads/2023/02/trading-bot-machine-learning-tutorial-gateio-trading-signals-python-min.png 300w" sizes="(max-width: 748px) 100vw, 748px" /><figcaption class="wp-element-caption">Bots can do a lot of cool things but should be used with caution. Image created with <a href="http://www.midjourney.com" target="_blank" rel="noreferrer noopener">Midjourney</a></figcaption></figure>
</div>
</div>
</div>
</div>



<h2 class="wp-block-heading" id="h-different-modules-of-the-signal-bot">Different Modules of the Signal Bot </h2>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>This section briefly describes the conceptual architecture of the Crypto Twitter bot. Its architecture adheres to a modular design pattern and separates into four loosely coupled modules. Each module has a clear function.</p>



<ol class="wp-block-list">
<li>The <strong>Data Collection Module retrieves price data from the crypto exchange Gate.io. The module sends requests at </strong>regular intervals against the gate.io API. The module adds the data to separate data stores &#8211; one for each cryptocurrency. It then forwards the data to the preprocessing module.</li>



<li>The<strong> Data Preprocessing Module</strong> calculates the statistical indicators, such as moving averages or means, which become the basis for the signaling logic.</li>



<li>The <strong>Signaling Module </strong>searches for relevant events based on the indicator values provided. If a relevant event is detected, it is reported to the communication module.</li>



<li>The <strong>Communication Module</strong> connects to the Twitter API. As soon as it is informed about a new event, it tweets about this event on Twitter.</li>
</ol>



<p>Now that you are familiar with the modules of our Crypto Twitter Bot, we can take a look at its underlying APIs.</p>



<figure class="wp-block-image size-large is-resized is-style-default"><img decoding="async" data-attachment-id="6092" data-permalink="https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/image-124/#main" data-orig-file="https://www.relataly.com/wp-content/uploads/2022/03/image.png" data-orig-size="1342,865" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://www.relataly.com/wp-content/uploads/2022/03/image.png" src="https://www.relataly.com/wp-content/uploads/2022/03/image-1024x660.png" alt="" class="wp-image-6092" width="611" height="394" srcset="https://www.relataly.com/wp-content/uploads/2022/03/image.png 1024w, https://www.relataly.com/wp-content/uploads/2022/03/image.png 300w, https://www.relataly.com/wp-content/uploads/2022/03/image.png 768w, https://www.relataly.com/wp-content/uploads/2022/03/image.png 1342w" sizes="(max-width: 611px) 100vw, 611px" /><figcaption class="wp-element-caption">Components of the Relataly Crypto Signal Bot</figcaption></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"></div>
</div>



<h2 class="wp-block-heading" id="h-about-the-apis-used-in-this-tutorial">About the APIs Used in this Tutorial</h2>



<p>In this tutorial, we will be using two APIs: </p>



<ul class="wp-block-list">
<li>The Gate.io API to fetch price data.</li>



<li>Twitter to post Tweets about Trading Signals</li>
</ul>



<h3 class="wp-block-heading" id="h-the-gate-io-api">The Gate.io API</h3>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>Firstly, we will be using the Gate.io API to obtain prices for various cryptocurrencies. Gate.io is one of the smaller crypto exchanges in the crypto-verse. However, it offers a wide range of smaller cryptocurrencies, especially those you cannot trade anywhere else. As of now, the gate.io market endpoint does not require authentication to use its essential functions.</p>



<p>Check out our <a href="https://www.relataly.com/streaming-crypto-prices-via-the-gate-io-api-with-python/3982/" target="_blank" rel="noreferrer noopener">recent relataly gate.io tutorial</a> to learn how to pull data via the gate.io API in Python.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"></div>
</div>



<h3 class="wp-block-heading" id="h-the-twitter-api">The Twitter API</h3>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>The second API that our bot will use is the Twitter API. We will use this API via the Python package Tweepy to post crypto price signals. Check out this article if you are looking for a simple code example of submitting tweets via the Twitter API. If you don&#8217;t want to use Twitter, you can disable its use in the code.</p>



<p>Posting tweets via the API requires authentication with a valid developer account. You can apply for a developer account for free on the Twitter <a href="https://developer.twitter.com/en/apply-for-access" target="_blank" rel="noreferrer noopener">developer website</a>. Just be aware that the confirmation can sometimes take several days. </p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"></div>
</div>



<h3 class="wp-block-heading" id="storing-the-api-key">Storing the Twitter API Key</h3>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>Storing API keys in your code can compromise the security of your application. If the code is made public, for example, by publishing it on a code-sharing website like GitHub, anyone who has access to the code can use the API key to make requests to the API and potentially access sensitive information or cause harm to your account or application. A better practice is to import and access the API key from a separate YAML file, from where you can import it into your project. To store the Twitter API Key, create a YAML file with the name “api_config_twitter.yml” and insert your API key into this file as follows:</p>



<p>api_<em>key: “your api key”</em></p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"></div>
</div>



<h2 class="wp-block-heading" id="h-implementing-a-twitter-signal-bot-using-python">Implementing a Twitter Signal Bot using Python</h2>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>In this article, we will walk through the process of creating a Twitter bot that automatically tweets updates about cryptocurrency prices. The bot will be designed to pull real-time data on cryptocurrency prices from an external API, and then automatically generate and post tweets on a regular basis. By the end of the article, you will have a fully functional Twitter bot that can keep your followers informed about the latest cryptocurrency prices.</p>



<p>Note: You require a Twitter developer account if you want to use the Twitter functionality. Without an account, you can still print out trading signals to yourself, but you will not be able to post them via the Twitter API. </p>



<p>The code is available on the GitHub repository.</p>



<div class="wp-block-kadence-advancedbtn kb-buttons-wrap kb-btns_41cd8e-1f"><a class="kb-button kt-button button kb-btn_290c88-96 kt-btn-size-standard kt-btn-width-type-full kb-btn-global-inherit  kt-btn-has-text-true kt-btn-has-svg-true  wp-block-button__link wp-block-kadence-singlebtn" href="https://github.com/flo7up/relataly-public-python-tutorials/blob/master/08%20Natural%20Language%20Processing/025%20Bots%20-%20Building%20a%20Twitter%20Bot%20with%20Python.ipynb" target="_blank" rel="noreferrer noopener"><span class="kb-svg-icon-wrap kb-svg-icon-fe_eye kt-btn-icon-side-left"><svg viewBox="0 0 24 24"  fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"  aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></span><span class="kt-btn-inner-text">View on GitHub </span></a>

<a class="kb-button kt-button button kb-btn_de3f80-09 kt-btn-size-standard kt-btn-width-type-full kb-btn-global-inherit  kt-btn-has-text-true kt-btn-has-svg-true  wp-block-button__link wp-block-kadence-singlebtn" href="https://github.com/flo7up/relataly-public-python-API-tutorials" target="_blank" rel="noreferrer noopener"><span class="kb-svg-icon-wrap kb-svg-icon-fa_github kt-btn-icon-side-left"><svg viewBox="0 0 496 512"  fill="currentColor" xmlns="http://www.w3.org/2000/svg"  aria-hidden="true"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg></span><span class="kt-btn-inner-text">Relataly GitHub Repo </span></a></div>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<p class="has-accent-color has-blush-light-purple-gradient-background has-text-color has-background"><strong>Disclaimer</strong>: This article does not constitute financial advice. Stock markets can be very volatile and are generally difficult to predict. Predictive models and other forms of analytics applied in this article only illustrate machine learning use cases.</p>
</div>
</div>



<h3 class="wp-block-heading" id="h-python-prerequisites">Python Prerequisites</h3>



<p>Before starting the coding part, make sure that you have set up your Python 3 environment and required packages. If you don&#8217;t have an environment set up yet, you can follow&nbsp;this tutorial&nbsp;to set up the&nbsp;<a href="https://www.anaconda.com/products/individual" target="_blank" rel="noreferrer noopener">Anaconda environment</a>.</p>



<p>Also, make sure you install all required packages. In this tutorial, we will be working with the following standard packages:&nbsp;</p>



<ul class="wp-block-list">
<li><em><a href="https://pandas.pydata.org/" target="_blank" rel="noreferrer noopener">pandas</a></em></li>



<li><em><a href="https://numpy.org/" target="_blank" rel="noreferrer noopener">NumPy</a></em></li>
</ul>



<p>In addition, we will use the following two packages:</p>



<ul class="wp-block-list">
<li>Firstly, the gate.io package (<a href="https://github.com/gateio/gateapi-python" target="_blank" rel="noreferrer noopener">package name gate-API</a>) pulls crypto price data from gate.io.</li>



<li>Secondly, we will use the Twitter API library <a href="https://www.tweepy.org/" target="_blank" rel="noreferrer noopener">Tweepy</a> to post trading signals via the <a href="https://developer.twitter.com/en/docs/twitter-api" target="_blank" rel="noreferrer noopener">Twitter API</a>.</li>
</ul>



<p>You can install packages using console commands:</p>



<ul class="wp-block-list">
<li><em>pip install &lt;package name&gt;</em></li>



<li><em>conda install &lt;package name&gt;</em>&nbsp;(if you are using the anaconda packet manager)</li>
</ul>



<h3 class="wp-block-heading" id="h-step-1-regular-retrieval-of-price-data">Step #1: Regular Retrieval of Price Data </h3>



<p>First, we will define a &#8220;prices&#8221; class to handle the incoming data flow. The prices class contains a &#8220;get_latest_prices&#8221; attribute that retrieves price information from gate.io. The function regularly calls the gate.io list_ticker market endpoint.</p>



<p>The list_ticker endpoint returns a list of data fields for cryptocurrency pairs. Examples of price pairs are BTC_USD, BTC_ETH, BTC_ADA, etc. We can limit the response to a single price pair by passing a single pair as a variable in the API call. However, it is not possible to restrict the response to multiple pairs. We either get data for a single pair or all pairs. The response contains a list of the following data fields:</p>



<figure class="wp-block-image is-resized"><img decoding="async" src="https://www.relataly.com/wp-content/uploads/2021/05/image-5-1024x581.png" alt="Response returned by the Gate.io API list_tickers operation" width="493" height="280"/><figcaption class="wp-element-caption">Overview of the data fields in the response</figcaption></figure>



<p>The following code maintains a separate dictionary for each cryptocurrency pair. The dictionary contains the name of the cryptocurrency pair and a data frame that includes the price data history. Each time the crypto bot receives a new response from the API, it goes through the response, extracts the price data(Price, Volume, etc.), and appends this data to the Data Frame of the respective cryptocurrency pair. Then the information is passed to the preprocessing module.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">import pandas as pd
import numpy as np
import json
import requests
import datetime as dt
import logging
import threading
import time
from __future__ import print_function

import tweepy 
import gate_api
from gate_api.exceptions import ApiException, GateApiException
from twitter_secrets import twitter_secrets as ts # place the twitter_secrets file under &lt;User&gt;/anaconda3/Lib

class Prices:
    &quot;&quot;&quot;Class that uses the gate api to retrieve currency data.&quot;&quot;&quot;

    def __init__(self, config):
        self._config = config
        self._logger = logging.getLogger(__name__)
        configuration = gate_api.Configuration(host=&quot;https://api.gateio.ws/api/v4&quot;)
        api_client = gate_api.ApiClient(configuration)
        self._api_instance = gate_api.SpotApi(api_client)
        self._price_history = {}
        self._cont_update_thread = None
        self._stop_cont_update_thread = None
        self._price_history_lock = threading.Lock()

    def get_price_history(self):
        &quot;&quot;&quot;Returns a dictionary with the price histories for the currencies.&quot;&quot;&quot;
        return self._price_history, self._price_history_lock

    def get_latest_prices(self):
        &quot;&quot;&quot;Gets new price data and adds the values to a DataFrame.

        Returns the DataFrame in a dictionary with the currencies as keys.&quot;&quot;&quot;
        timestamp = dt.datetime.now()
        try:
            api_response = self._api_instance.list_tickers()
        except GateApiException as e:
            logging.warning(
                &quot;Gate api exception, label: %s, message: %s\n&quot; % (e.label, e.message)
            )
            return {}
        except ApiException as e:
            logging.warning(&quot;Exception when calling SpotApi-&gt;list_tickers: %s\n&quot; % e)
            return {}
        latest_prices = {}
        for response in api_response:
            currency = response.currency_pair
            if &quot;USDT&quot; not in currency or &quot;BEAR&quot; in currency:
                continue
            value_dict = {
                &quot;base_volume&quot;: pd.to_numeric(response.base_volume),
                &quot;change_percentage&quot;: pd.to_numeric(response.change_percentage),
                &quot;etf_leverage&quot;: pd.to_numeric(response.etf_leverage),
                &quot;etf_net_value&quot;: pd.to_numeric(response.etf_net_value),
                &quot;etf_pre_net_value&quot;: pd.to_numeric(response.etf_pre_net_value),
                &quot;etf_pre_timestamp&quot;: response.etf_pre_timestamp,
                &quot;high_24h&quot;: pd.to_numeric(response.high_24h),
                &quot;highest_bid&quot;: pd.to_numeric(response.highest_bid),
                &quot;high_bid&quot;: pd.to_numeric(response.highest_bid),
                &quot;last&quot;: pd.to_numeric(response.last),
                &quot;low_24h&quot;: pd.to_numeric(response.low_24h),
                &quot;lowest_ask&quot;: pd.to_numeric(response.lowest_ask),
                &quot;quote_volume&quot;: pd.to_numeric(response.quote_volume),
                &quot;timestamp&quot;: timestamp,
            }
            latest_prices[currency] = pd.DataFrame(value_dict, index=[1])
        return latest_prices

    def start_cont_update(self):
        self._stop_cont_update_thread = threading.Event()
        self._stop_cont_update_thread.clear()
        self._cont_update_thread = threading.Thread(
            target=self._cont_update,
            args=(
                self._stop_cont_update_thread,
                self._price_history_lock,
            ),
        )
        self._cont_update_thread.start()
        self._logger.info(&quot;Started continuous price logging&quot;)

    def _cont_update(self, stop_event, lock):
        &quot;&quot;&quot;Continuously adds new prices to the price history.&quot;&quot;&quot;
        while not stop_event.is_set():
            start_time = time.time()
            lock.acquire()
            for currency, df in self.get_latest_prices().items():
                if currency in self._price_history.keys():
                    self._price_history[currency] = self._price_history[
                        currency
                    ].append(df, ignore_index=True)
                else:
                    self._price_history[currency] = df
            lock.release()
            self._logger.debug(&quot;Currency_dfs updated&quot;)
            self._wait_before_update(start_time)

    def _wait_before_update(self, start_time):
        elapsed_time = time.time() - start_time
        self._logger.debug(f&quot;Elapsed time: {elapsed_time}&quot;)
        if elapsed_time &gt; self._config[&quot;price_update_delay&quot;]:
            delay = 0
            self._logger.warning(
                #&quot;It took longer to retrieve the price data than the update_delay!&quot;
            )
        else:
            delay = self._config[&quot;price_update_delay&quot;] - elapsed_time
        self._logger.debug(f&quot;Waiting {delay}s until next update&quot;)
        time.sleep(delay)
</pre></div>



<h3 class="wp-block-heading" id="h-step-2-calculate-indicator-values">Step #2: Calculate Indicator Values</h3>



<p>Next, we will define a few functions that process the regular data inflow from gate.io and calculate indicator values for the different cryptocurrencies. </p>



<p>Absolute price values signal the bot that the price moves up or down. However, our signaling logic will primarily work with thresholds on percentage values. These indicators have a p at the end of the name in the code below.</p>



<p>In addition, we will avoid misleading signals by incorporating moving averages into the signaling logic. Moving averages work on historical data, so we have to hand over the price history when we call the &#8220;calc_indicators&#8221; function. Furthermore, we take over other indicators from the data frame, including the 24h_low and the 24h_high. These indicators give us additional information about the indicators of the preceding price points. We can use them to build more robust trading signals.</p>



<p>All indicators are calculated separately for each crypto pair, passed to a dictionary, and then passed to the signaling logic. In the next step, we can use these indicator values in our signaling rules.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">def calc_indicators(price_history):
    indicators = {}
    indicators_over_all = calc_indicators_over_all(price_history)
    for currency, df in price_history.items():
        if len(df) &lt;= 2:
            logging.getLogger().debug(
                f&quot;Skipped '{currency} when calculating indicators due to a lack of information&quot;
            )
            continue
        volume = df[&quot;base_volume&quot;].iloc[-1]
        last_price = df[&quot;last&quot;].iloc[-1]
        moving_avg_price = df[&quot;last&quot;].mean()
        moving_average_volume = df[&quot;base_volume&quot;].mean()
        moving_average_deviation_percent = np.round(
            div(last_price, moving_avg_price) - 1, 2
        )

        price_before = df[&quot;last&quot;].iloc[-2]
        price_delta = last_price - price_before
        price_delta_p = div(price_delta, last_price)
        price_delta_before = price_before - df[&quot;last&quot;].iloc[-3]
        price_delta_p_before = div((price_before - df[&quot;last&quot;].iloc[-3]), price_before)
        low_24h = df[&quot;low_24h&quot;].iloc[-1]
        high_24h = df[&quot;high_24h&quot;].iloc[-1]
        low_high_diff_p = div(high_24h - low_24h, low_24h)
        change_percentage = df[&quot;change_percentage&quot;].iloc[-1]

        indicator_values = {
            &quot;last_price&quot;: last_price,
            &quot;price_before&quot;: price_before,
            &quot;volume&quot;: volume,
            &quot;moving_avg_price&quot;: moving_avg_price,
            &quot;moving_average_volume&quot;: moving_average_volume,
            &quot;moving_average_deviation_percent&quot;: moving_average_deviation_percent,
            &quot;price_delta_p&quot;: price_delta_p,
            &quot;price_delta&quot;: price_delta,
            &quot;price_delta_before&quot;: price_delta_before,
            &quot;price_delta_p_before&quot;: price_delta_p_before,
            &quot;high_24h&quot;: high_24h,
            &quot;low_24h&quot;: low_24h,
            &quot;low_high_diff_p&quot;: low_high_diff_p,
            &quot;change_percentage&quot;: change_percentage,
        }
        indicator_values.update(indicators_over_all)
        indicators[currency] = indicator_values
    return indicators


def calc_indicators_over_all(price_history):
    avg_change_p = 0
    for currency, df in price_history.items():
        avg_change_p += df[&quot;change_percentage&quot;].iloc[-1]
    nr_of_currencies = len(price_history)
    avg_change_p = div(avg_change_p, nr_of_currencies)
    values = {
        &quot;avg_change_p&quot;: avg_change_p,
    }
    return values


def div(dividend, divisor, alt_value=0.0):
    return dividend / divisor if divisor != 0 else alt_value</pre></div>



<h3 class="wp-block-heading" id="h-step-3-define-the-signaling-logic-of-the-twitter-bot">Step #3: Define the Signaling Logic of the Twitter Bot</h3>



<p>Our bot will use a signaling logic that differentiates between the following price signals:</p>



<ul class="wp-block-list">
<li>A simple uptick: Price_delta_p must be higher than the threshold (10%) to trigger.</li>



<li>A simple downtick: Price_delta_p must be lower than the threshold (10%) to trigger.</li>



<li>The bot does also report on new 24-hour lows and highs</li>



<li>Another event on which the bot reports is when an up or down price trend begins to accelerate or slows down.</li>



<li>The bot reports that when a price performs a trend reversal (pullback and recovery)</li>
</ul>



<p></p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" data-attachment-id="5034" data-permalink="https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/image-71-2/#main" data-orig-file="https://www.relataly.com/wp-content/uploads/2021/06/image-71.png" data-orig-size="1168,639" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-71" data-image-description="" data-image-caption="" data-large-file="https://www.relataly.com/wp-content/uploads/2021/06/image-71.png" src="https://www.relataly.com/wp-content/uploads/2021/06/image-71-1024x560.png" alt="Overview of the different trading signals generated by the signaling logic, twitter bot, algorithmic trading" class="wp-image-5034" width="755" height="413" srcset="https://www.relataly.com/wp-content/uploads/2021/06/image-71.png 1024w, https://www.relataly.com/wp-content/uploads/2021/06/image-71.png 300w, https://www.relataly.com/wp-content/uploads/2021/06/image-71.png 768w, https://www.relataly.com/wp-content/uploads/2021/06/image-71.png 1168w" sizes="(max-width: 755px) 100vw, 755px" /><figcaption class="wp-element-caption">Overview of the different trading signals generated by the signaling logic</figcaption></figure>



<p>Be aware that the price_delta_p measures the percentage deviation from the previous price point. Thus, the signaling logic that our bot has in place is very dependent on the interval in which the bots request new price data. Shorter time intervals will have a lower chance of triggering because more considerable changes typically occur over a longer time. For more details regarding the signaling logic, please view the code below.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">def check_signal(currency, indicators, cs_config):
    ind = indicators[currency]
    signal = ''
    if (ind['moving_avg_price'] &gt; 0
            and ind['last_price'] &gt; 0.0
            and abs(ind['price_delta']) &gt; 0.0
            and abs(ind['price_delta_p']) &gt;= cs_config[&quot;delta_threshold_p&quot;]
            and ind['volume'] &gt; 0
    ):
        # up
        if ind['price_delta'] &gt; 0:
            movement_type = 'up +'
            if abs(ind['price_delta_p_before']) &gt; cs_config[&quot;delta_threshold_p&quot;]:
                if ind['price_delta_before'] &lt;= 0:
                    movement_type = 'recovery from ' + str(ind['price_before']) + ' to ' + str(ind['last_price'])
                else:
                    if ind['price_delta_p'] * (1-cs_config[&quot;delta_threshold_p&quot;]) &gt; ind['price_delta_p_before']:
                        movement_type = 'upward trend accelerates +'
                    elif ind['price_delta_p'] &lt; ind['price_delta_p_before'] * (1-cs_config[&quot;delta_threshold_p&quot;]):
                        movement_type = 'upward trend slows down +'
                    elif ind['price_delta_p'] * (1+cs_config[&quot;delta_threshold_p&quot;]) &gt;= ind['price_delta_p_before'] &gt;= ind['price_delta_p'] * (1-cs_config[&quot;delta_threshold_p&quot;]):
                        movement_type = 'upward trend continues +'
        # down
        elif ind['price_delta'] &lt; 0:
            movement_type = 'down '
            if abs(ind['price_delta_p_before']) &gt; cs_config[&quot;delta_threshold_p&quot;]:
                if ind['price_delta_before'] &gt; 0:
                    movement_type = 'pullback from ' + str(ind['price_before']) + ' to ' + str(ind['last_price'])
                else:
                    if ind['price_delta_p'] * (1-cs_config[&quot;delta_threshold_p&quot;]) &gt; ind['price_delta_p_before']:
                        movement_type = 'down trend accelerates '
                    elif ind['price_delta_p'] * (1+cs_config[&quot;delta_threshold_p&quot;]) &gt;= ind['price_delta_p_before'] &gt;= ind['price_delta_p'] * (1-cs_config[&quot;delta_threshold_p&quot;]):
                        movement_type = 'down trend continues '
                    elif ind['price_delta_p'] &lt; ind['price_delta_p_before'] * (1+cs_config[&quot;delta_threshold_p&quot;]):
                        movement_type = 'downward trend slows down '

        signal = get_signal_log(movement_type, currency, ind['price_delta_p'], ind['last_price'],
                                ind['moving_avg_price'], ind['volume'], ind['price_delta'], ind['change_percentage'],
                                ind['high_24h'], ind['low_24h'], ind['low_high_diff_p'])

        check_24h_peak(currency, ind['last_price'], ind['low_24h'], ind['high_24h'])

    return signal
    # trade_signal


def check_24h_peak(currency, last_price, low_24h, high_24h):
    if last_price &lt; low_24h:
        print(currency + ' new 24h low $' + str(last_price))
    elif last_price &gt; high_24h:
        print(currency + ' new 24h high $' + str(last_price))


def get_signal_log(movement_type, currency, price_delta_p, last_price, moving_avg_price, volume, price_delta,
                   daily_up_p, high_24h, low_24h, low_high_diff_p):
    signal = f'{currency} {movement_type} ' \
             f'{np.round(price_delta_p * 100, 5)}% ' \
             f'MA:${np.round(moving_avg_price, 6)} ' \
             f'last_price:${np.round(last_price, 6)} ' \
             f'price delta:{np.round(price_delta, 6)} ' \
             f'volume:${np.round(volume, 1)} ' \
             f'daily_change:{np.round(daily_up_p, 2)}% ' \
             f'high_24h:${high_24h} ' \
             f'low_24h:${low_24h} ' \
             f'low_high_diff_p:{np.round(low_high_diff_p * 100, 2)}%'
    return signal</pre></div>



<h3 class="wp-block-heading" id="h-step-4-send-tweets-via-twitter">Step #4: Send Tweets via Twitter</h3>



<p>Next, we define a simple function that calls the Twitter API and tweets our price signal. Because the Twitter API requires authentication, you must provide the API authentication credentials from a valid Twitter developer account. </p>



<p>It&#8217;s best not to store the API credentials directly in code. Still not perfect, but slightly better is to keep the data in a separate python file (for example, called &#8220;twitter_secrets&#8221;) that you put into your package folder (for example, under /anaconda3/Lib), from where you can import it directly into your code. </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}"># Twitter Consumer API keys
CONSUMER_KEY    = &quot;api123&quot;
CONSUMER_SECRET = &quot;api123&quot;

# Twitter Access token &amp; access token secret
ACCESS_TOKEN    = &quot;api123&quot;
ACCESS_SECRET   = &quot;api123&quot;

BEARER_TOKEN = &quot;api123&quot;

class TwitterSecrets:
    &quot;&quot;&quot;Class that holds Twitter Secrets&quot;&quot;&quot;

    def __init__(self):
        self.CONSUMER_KEY    = CONSUMER_KEY
        self.CONSUMER_SECRET = CONSUMER_SECRET
        self.ACCESS_TOKEN    = ACCESS_TOKEN
        self.ACCESS_SECRET   = ACCESS_SECRET
        self.BEARER_TOKEN   = BEARER_TOKEN
        
        # Tests if keys are present
        for key, secret in self.__dict__.items():
            assert secret != &quot;&quot;, f&quot;Please provide a valid secret for: {key}&quot;

twitter_secrets = TwitterSecrets()</pre></div>



<p>Once you have imported the file, you can then load the API credentials from the file in the following way: </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">consumer_key = ts.CONSUMER_KEY
consumer_secret = ts.CONSUMER_SECRET
access_token = ts.ACCESS_TOKEN
access_secret = ts.ACCESS_SECRET

### Print API Auth Data (leave disabled for security reasons)
# print(f'consumer_key: {consumer_key}')
# print(f'consumer_secret: {consumer_secret}')
# print(f'access_token: {access_token}')
# print(f'access_secret: {access_token}')

#authenticating to access the twitter API
auth=tweepy.OAuthHandler(consumer_key,consumer_secret)
auth.set_access_token(access_token,access_secret)
api=tweepy.API(auth)

def send_pricechange_tweet(signal):
    api.update_status(f&quot;{signal} \n {relataly_url}&quot;)</pre></div>



<h3 class="wp-block-heading" id="h-step-5-starting-the-crypto-signal-bot">Step #5 Starting the Crypto Signal Bot</h3>



<p>Finally, we can hit the start button of our crypto signal bot. But before we do this, take a look at some configuration options of the bot.</p>



<ul class="wp-block-list">
<li>CYCLE_DELAY is the standard interval in seconds in which the bot will call the gate.io API. </li>



<li>CURRENCY_PAIR is another API parameter limiting the cryptocurrency pairs to specific currency pairs. The bot will scan the entire market with all currency pairs in the standard setting, including all USDT pairs.</li>



<li>TWITTER_ACTIVE defines whether the bot posts signals on Twitter. Be aware that your bot may instantly report any signal on your Twitter account if you enable it. </li>



<li>RUNS defines the max number of prices that the bot will retrieve before the bot stops. </li>
</ul>



<p>Now, let&#8217;s test the bot:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">RUNS = 50 # the bot will stop after 50 price points
CYCLE_DELAY = 20 # the interval for checking the data and retrieving another price point
EVAL_PRICES_DELAY = 10
CURRENCY_PAIR = &quot;&quot; # the bot will retrieve data for all currency pairs listed on gate.io
PRICES_CONFIG = {&quot;price_update_delay&quot;: 20}
TWITTER_ACTIVE = False

CHECK_SIGNAL_CONFIG = {
    &quot;moving_avg_threshold_down_p&quot;: 0.10,
    &quot;moving_avg_threshold_up_p&quot;: 0.10,
    &quot;delta_threshold_p&quot;: 0.07,
    'enable_twitter': TWITTER_ACTIVE,
}

if __name__ == &quot;__main__&quot;:
    logging.basicConfig(
        level=logging.INFO, format=&quot;\033[02m%(asctime)s %(levelname)s: %(message)s&quot;
    )
    logger = logging.getLogger(__name__)
    prices = Prices(PRICES_CONFIG)
    prices.start_cont_update()
    currency_dfs = {}
    logging.info(f&quot;Crypto bot is starting - please wait&quot;)
    logger.info(f&quot;Collecting crypto data from gate.io for {EVAL_PRICES_DELAY}s&quot;)
    time.sleep(EVAL_PRICES_DELAY)
    logger.info(f&quot;\n&lt;&lt; Crypto signal bot started :-) &gt;&gt;&quot;)
    logger.info(f&quot;&lt;&lt; Checking prices every {CYCLE_DELAY} seconds &gt;&gt;&quot;)
    logger.info(f&quot;Now checking for signals - please wait\n&quot;)
    for i in range(RUNS):
        price_history, lock = prices.get_price_history()
        lock.acquire()
        indicators = calc_indicators(price_history)
        lock.release()
        for currency in indicators.keys():
            if not indicators[currency]:
                continue
            signal = check_signal(
                currency,
                indicators,
                CHECK_SIGNAL_CONFIG,
            )
            if signal:
                logger.info(signal)
                if CHECK_SIGNAL_CONFIG['enable_twitter']:
                    send_pricechange_tweet(signal)
                    print('send via twitter')
        time.sleep(CYCLE_DELAY)</pre></div>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:false,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;null&quot;,&quot;mime&quot;:&quot;text/plain&quot;,&quot;theme&quot;:&quot;3024-day&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Plain Text&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;text&quot;}">2022-03-09 11:40:38,939 INFO: Started continuous price logging
2022-03-09 11:40:38,940 INFO: Crypto bot is starting - please wait
2022-03-09 11:40:38,940 INFO: Collecting crypto data from gate.io for 10s
2022-03-09 11:40:48,941 INFO: 
&lt;&lt; Crypto signal bot started :-) &gt;&gt;
2022-03-09 11:40:48,942 INFO: &lt;&lt; Checking prices every 20 seconds &gt;&gt;
2022-03-09 11:40:48,942 INFO: Now checking for signals - please wait

2022-03-09 11:52:06,800 INFO: EOSBULL_USDT up + 19.42446% MA:$1.1e-05 last_price:$1.4e-05 price delta:3e-06 volume:$1272326905.1 daily_change:33.65% high_24h:$1.16e-05 low_24h:$9.8e-06low_high_diff_p:18.37%
EOSBULL_USDT new 24h high $1.39e-05
send via twitter</pre></div>



<p> And this is what the tweets will look like on Twitter:</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" data-attachment-id="4060" data-permalink="https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/image-11-10/#main" data-orig-file="https://www.relataly.com/wp-content/uploads/2021/05/image-11.png" data-orig-size="788,724" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-11" data-image-description="" data-image-caption="" data-large-file="https://www.relataly.com/wp-content/uploads/2021/05/image-11.png" src="https://www.relataly.com/wp-content/uploads/2021/05/image-11.png" alt="output of our twitter bot, signalling logic, algorithmic trading, crypto price bot, gateio" class="wp-image-4060" width="512" height="470" srcset="https://www.relataly.com/wp-content/uploads/2021/05/image-11.png 788w, https://www.relataly.com/wp-content/uploads/2021/05/image-11.png 300w, https://www.relataly.com/wp-content/uploads/2021/05/image-11.png 768w" sizes="(max-width: 512px) 100vw, 512px" /></figure>



<h2 class="wp-block-heading" id="h-summary">Summary</h2>



<p>Congratulations on completing this tutorial! In this article, you learned how to build a Python-based Twitter crypto signal bot. When run, the bot will regularly retrieve cryptocurrency quotes from the Gate.io exchange and tweet about any price movements based on a simple signaling logic.</p>



<p>While the signaling logic in this tutorial is kept simple, this basic framework provides a foundation for you to further develop and enhance the signaling rules. For example, you could consider using volume or price volatility changes as the basis for defining signals. Have fun experimenting and expanding upon this project!</p>



<p>If you found this article helpful, please show your appreciation by leaving a comment. Cheers</p>



<h2 class="wp-block-heading" id="h-sources-and-further-reading">Sources and Further Reading</h2>



<ol class="wp-block-list"><li><a href="https://amzn.to/3MyU6Tj" target="_blank" rel="noreferrer noopener">Charu C. Aggarwal (2018) Neural Networks and Deep Learning</a></li><li><a href="https://amzn.to/3yIQdWi" target="_blank" rel="noreferrer noopener">Jansen (2020) Machine Learning for Algorithmic Trading: Predictive models to extract signals from market and alternative data for systematic trading strategies with Python</a></li><li><a href="https://amzn.to/3S9Nfkl" target="_blank" rel="noreferrer noopener">Aurélien Géron (2019) Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems </a></li><li><a href="https://amzn.to/3EKidwE" target="_blank" rel="noreferrer noopener">David Forsyth (2019) Applied Machine Learning Springer</a></li><li><a href="https://amzn.to/3MAy8j5" target="_blank" rel="noreferrer noopener">Andriy Burkov (2020) Machine Learning Engineering</a></li></ol>



<p class="has-contrast-2-color has-base-3-background-color has-text-color has-background"><em>The links above to Amazon are affiliate links. By buying through these links, you support the Relataly.com blog and help to cover the hosting costs. Using the links does not affect the price.</em></p>
<p>The post <a href="https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/">Automate Crypto Trading with a Python-Powered Twitter Bot and Gate.io Signals</a> appeared first on <a href="https://www.relataly.com">relataly.com</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.relataly.com/building-a-twitter-bot-for-trading-signals-using-python/3974/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3974</post-id>	</item>
	</channel>
</rss>
