
{"id":41844,"date":"2025-02-05T10:45:08","date_gmt":"2025-02-05T10:45:08","guid":{"rendered":"https:\/\/mycryptomania.com\/?p=41844"},"modified":"2025-02-05T10:45:08","modified_gmt":"2025-02-05T10:45:08","slug":"crypto-trading-bot-in-alpaca","status":"publish","type":"post","link":"https:\/\/mycryptomania.com\/?p=41844","title":{"rendered":"Crypto Trading Bot in Alpaca"},"content":{"rendered":"<p>The goal of this story is to create the simplest paper trading bot in <em>Alpaca<\/em> which will use WebSocket 1-minute bars. The strategy\u00a0is<\/p>\n<p>Buy 0.1 BTC at Market if RSI_14 &lt; 30 and HAVE_NO_POSITIONSell 0.1 BTC at Market if RSI_14 &gt; 70 and HAVE_POSITION<\/p>\n<h3>YouTube Video<\/h3>\n<p><a href=\"https:\/\/medium.com\/media\/61d42518884e876d57f7a501b30f2eaf\/href\">https:\/\/medium.com\/media\/61d42518884e876d57f7a501b30f2eaf\/href<\/a><\/p>\n<h3>Installations<\/h3>\n<p>Install <em>alpaca-py<\/em>!pip install aplaca-py<\/p>\n<p>2. Install <em>pandas_ta<\/em><\/p>\n<p>!pip install pandas_ta<\/p>\n<h3>API Keys +\u00a0Secrets<\/h3>\n<p>from google.colab import userdata<br \/>ALPACA_API_KEY=userdata.get(&#8216;ALPACA_API_KEY&#8217;)<br \/>ALPACA_API_SECRET=userdata.get(&#8216;ALPACA_API_SECRET&#8217;)<\/p>\n<h3>Nest Asyncio<\/h3>\n<p>Allow nested use of <em>asyncio <\/em>within <em>Jupyter notebooks<\/em>, <em>Google Colab<\/em>, or other environments that already have an event loop\u00a0running.Written by the legend Ewald De Wit\u00a0RIPimport nest_asyncio <\/p>\n<p>nest_asyncio.apply()<\/p>\n<h3>Initialize Paper Trading\u00a0Client<\/h3>\n<p>from alpaca.trading.client import TradingClient<br \/>trading_client = TradingClient(ALPACA_API_KEY, ALPACA_API_SECRET, paper=True)<\/p>\n<h3>Crypto Data Stream for Websocket Data<\/h3>\n<p><strong>Initialize <em>CryptoDataStream<\/em><\/strong><\/p>\n<p>Used to manage real-time Crypto Websocket data.from alpaca.data.live import CryptoDataStream<\/p>\n<p>crypto_data_stream = CryptoDataStream(ALPACA_API_KEY, ALPACA_API_SECRET)<\/p>\n<p><strong>Define Event Handler when New Bar\u00a0Arrives<\/strong><\/p>\n<p>This is where we put our trading\u00a0logicAnalogous to <em>callback <\/em>in <em>ib_insync<\/em>from alpaca.trading.requests import MarketOrderRequest<br \/>from alpaca.trading.enums import OrderSide, TimeInForce<br \/>from pandas_ta.momentum import rsi<br \/>bars = []<br \/>has_position = False<br \/>async def on_new_bar(bar):<br \/>  global bars<br \/>  global has_position<\/p>\n<p>  bars.append(bar)<\/p>\n<p>  if len(bars)&lt;15:<br \/>    print(&#8220;Not Enough Data&#8221;)<\/p>\n<p>  else:<br \/>    rsi_value = rsi(util.df(bars[-15:]).close).iloc[-1]<br \/>    print(f&#8221;Current RSI is {rsi_value}&#8221;)<\/p>\n<p>    if has_position and rsi_value&gt;=70:<br \/>      print(&#8220;RSI is overbought, sell BTC&#8221;)<br \/>      trading_client.submit_order(<br \/>              order_data=MarketOrderRequest(<br \/>              symbol=&#8221;BTC\/USD&#8221;,<br \/>              qty=.1,<br \/>              side=OrderSide.SELL,<br \/>              time_in_force=TimeInForce.GTC<br \/>              )<br \/>      )<br \/>      has_position = False<br \/>    elif not has_position and rsi_value&lt;=30:<br \/>      print(&#8220;RSI is oversold, buy BTC&#8221;)<br \/>      trading_client.submit_order(<br \/>              order_data=MarketOrderRequest(<br \/>              symbol=&#8221;BTC\/USD&#8221;,<br \/>              qty=.1,<br \/>              side=OrderSide.BUY,<br \/>              time_in_force=TimeInForce.GTC<br \/>              )<br \/>      )<br \/>      has_position = TrueNote we used the following helper function <em>util.df <\/em>to convert a list of bars into a <em>Pandas DataFrame<\/em>import pandas as pd<br \/>class util:<br \/>    @staticmethod<br \/>    def df(json_like):<br \/>        if isinstance(json_like, list):<br \/>            json_like = [element.__dict__ for element in json_like]<br \/>            return pd.DataFrame(json_like)<br \/>        else:<br \/>            json_like = json_like.__dict__<br \/>            return pd.DataFrame(json_like.values(), index=json_like.keys())<\/p>\n<p><strong>Subscribe to Websocket 1-minute Bars and attach Event\u00a0Handler<\/strong><\/p>\n<p>crypto_data_stream.subscribe_bars(on_new_bar, &#8220;BTC\/USD&#8221;)<\/p>\n<p><strong>Run the Algo (BLOCKING)<\/strong><\/p>\n<p>crypto_data_stream.run()<\/p>\n<p><strong>Run the Algo (NON BLOCKING)<\/strong><\/p>\n<p>import asyncio<br \/>asyncio.create_task(crypto_data_stream._run_forever())If you are using <em>Jupyter\/Colab<\/em> and still want it to be Interactive this is\u00a0useful<\/p>\n<p><strong>Sample Output:<\/strong><\/p>\n<p><a href=\"https:\/\/medium.com\/coinmonks\/rsi-crypto-bot-in-alpaca-ad2585f225db\">Crypto Trading Bot in Alpaca<\/a> was originally published in <a href=\"https:\/\/medium.com\/coinmonks\">Coinmonks<\/a> on Medium, where people are continuing the conversation by highlighting and responding to this story.<\/p>","protected":false},"excerpt":{"rendered":"<p>The goal of this story is to create the simplest paper trading bot in Alpaca which will use WebSocket 1-minute bars. The strategy\u00a0is Buy 0.1 BTC at Market if RSI_14 &lt; 30 and HAVE_NO_POSITIONSell 0.1 BTC at Market if RSI_14 &gt; 70 and HAVE_POSITION YouTube Video https:\/\/medium.com\/media\/61d42518884e876d57f7a501b30f2eaf\/href Installations Install alpaca-py!pip install aplaca-py 2. Install pandas_ta [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-41844","post","type-post","status-publish","format-standard","hentry","category-interesting"],"_links":{"self":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/41844"}],"collection":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=41844"}],"version-history":[{"count":0,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/41844\/revisions"}],"wp:attachment":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=41844"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=41844"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=41844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}