December 14, 2018

KloudTrader Narwhal

Intro

We built LibKloudTrader so that anyone, regardless of whether they are a professional algorithmic trader or simply a beginner dabbling in finance, can rapidly prototype their strategies in Python (support for more languages coming soon) and deploy them on Narwhal, our managed computational finance platform. No matter how complex your model/algorithm/strategy is, it can easily be made market-ready once our APIs are used. LibKloudTrader, our trading framework optimized is for Narwhal, is one our open source initiatives. As always, we welcome your contributions and feedback to help us better serve the quantitative and algorithmic trading community.

In this post, we are going to talk about how to create a strategy with LibKloudTrader and how you can leverage the alert_me feature provided by us to create a real-time alerts system. We will begin with a brief overview, followed by a demonstration of using LibKloudTrader’s alert_me with a mean-reversion strategy written in python.

Algorithmic Trading

For those of who may be new to trading but have a basic familiarity with computers will easily understand that programming is the key to automation. Stock trading is one of the earliest applications of computer networking. Programming not only provides automation capabilities that scale effortlessly but also allows us to simultaneously perform multiple calculations and computations in a matter of nanoseconds, a feat unmatched by anything else. This is why algorithmic trading has been growing exponentially lately. Algorithmic trading focuses on automating your trading decisions based on basic sophisticated decision systems, technical analysis and/or complex mathematical models. These set of rules that define your trading strategy are collectively known as an algorithm. There are several mathematical models, technical, portfolio and risk analysis functions that come with libkloudtrader which one can use to make decisions based on mathematical and quantitative analysis instead of arbitrary human decisions. Python is the implementation language as it is one of the most popular languages in finance. Through Narwhal, building algorithmic trading systems is incredibly simple e.g buying 5 shares of Apple can be done in one line.

buy('AAPL',5) # where AAPL is the symbol of Apple Inc. and 5 is the quantity of shares you want to buy.

Leveraging libkloudtrader’s Alert system to get real-time alerts

The alert_me module of libkloudtrader is one of the best features of Narwhal. Automation is great, but it is always useful to keep an eye on things when you are not in front of the trading terminal. This is where alert_me comes in. With alert_me API calls, you can customize what you get notified about, when you get notified and where you get notified.

libkloudtrader.alert_me provides three types of API calls which basically define where you get your alerts. You can get your alerts via:

SMS sms('+16xxxxxxxx','The alert you want to receive')

Email email('123@abc.com','The alert you want to receive')

SMS and Email sms_and_email('+16xxxxxxxx','123@abc.com','The alert you want to receive')

For more information and documentation on how to use alert_me module please visit the Alert section of libkloudtrader docs. We have tried our best to make the docs extremely easy to read and understand.

Mean Reversion Strategy

Now let’s build a Mean Reversion strategy using Python.

Mean reversion is a financial theory suggesting that asset prices and returns eventually return back to the long-run mean or average of the entire dataset. So basically a mean reversion strategy relies on any kind of moving average/mean to make trading decisions.

Let’s start by installing the dependencies needed for this algorithm:

Narwhal uses pipenv for installing your algorithm dependencies on your Python 3 Runtime.

pipenv install -e git+https://github.com/KloudTrader/libkloudtrader.git#egg=libkloudtrader pipenv install pandas

We will use pandas for structuring our data into DataFrames as libkloudtrader.analysis module's functions take dataframes as input.

Pipfile shall look like this:

[[source]]

url = "https://pypi.org/simple"

verify_ssl = true

name = "pypi"



[packages]

kloudtrader = {editable = true, git = "https://github.com/KloudTrader/libkloudtrader.git"}

pandas = "*"



[dev-packages]



[requires]

python_version = "3.7"

Now, we will create a file called main.py, that will contain our mean-reversion strategy.

Now, we will create a file called main.py that will contain our mean-reversion strategy.

Let’s start by importing the packages needed for our algorithm:

from libkloudtrader.defaults import *

from libkloudtrader.equities.data import close_prices, intraday_status

from libkloudtrader.user import account_positions,account_balance

from libkloudtrader.alert_me import *

from libkloudtrader.analysis import ema

import datetime

import pandas as pd



After importing the dependencies, we are going to create a function called analysis. This function will take an argument parameter symbol which is basically the symbol/ticker of the stock you want to trade. If you want to trade multiple stocks at a time, you can add more. The analysis function basically contains the following steps:

Get the Close prices data for the stock from the date of your preference till today. We are pulling close prices since January 1, 2018 for this example.

aapl_data=close_prices(symbol,'2018-09-01',datetime.date.today())

df=pd.DataFrame(aapl_data)

Calculate the Exponential mean average of last 3 or 4 months’ Close prices including today’s Last price. For this example, we are using a window of size 15, but you can choose any number according to your trading understanding. (We used EMA because it gives more weighting, or importance, to recent price data than as Simple Moving Average and as they say:- “Everything you need, is in the prices.”)

Calculate an Entry point for going Long/buying and another entry point for Selling the stocks. Entry point in this strategy is the price point where the algorithm shall enter the trade i.e. start trading. In this strategy, we are taking -5% of price as a Long Entry point and +5% of price for Selling entry point.

window=15

df['EMA']= ema(df['close'],n=window)

df['long_entry_point']=df['EMA']-(5/100)*df['EMA']

df['sell_entry_point']=df['EMA']+(5/100)*df['EMA']

df=df.iloc[window:] #ignores the rows with NaN values

Create Long/Buy and Sell entry signals based on the following conditions:

Buy Signal if the Close Price is less than the EMA as the price is expected to rise back to mean

Sell Signal if the Close Price is higher than the EMA as the price is expected to go back to mean

df['Buy']=df.apply(lambda x : 1 if x['close']<x['EMA'] else 0,axis=1)

df['Sell']=df.apply(lambda x : 1 if x['close']>x['EMA'] else 0,axis=1)

Thus, the analysis function looks like:

def analysis(symbol):

close_data=close_prices(symbol,'2018-01-01',datetime.date.today())

df=pd.DataFrame(close_data)

window=15

df['EMA']= ema(df['close'],n=window)

df['long_entry_point']=df['EMA']-(5/100)*df['EMA']

df['sell_entry_point']=df['EMA']+(5/100)*df['EMA']

df=df.iloc[window:]

df['Buy']=df.apply(lambda x : 1 if x['close']<x['EMA'] else 0,axis=1)

df['Sell']=df.apply(lambda x : 1 if x['close']>x['EMA'] else 0,axis=1)

return df

Next is the trading Logic:

The trading logic will be defined in a function called trade which also takes symbol as an argument.

Gather the data points for today.

today=str(datetime.date.today())

data=analysis(symbol.upper())

data=data.loc[data['date']==today]

This pretty self-explanatory. We pulled out the row that contains today’s data from the whole DataFrame. The data in this row gets updated after seconds throughout the trading day and as the Last traded price of a stock is always changing.

Define the entry and exit conditions of going long/buying:

If the signal is Buy, buy until the last traded price of the stock is less than the long entry point and exit if funds/amount/cash in your brokerage account is greater than or equal to “Amount of your choice”. Or there can be any other exit condition, like buy till you hold 50 of AAPL stocks.

Define the entry and exit conditions of selling:

If the signal is Sell, sell until the last traded price of the stock is higher than the sell entry point and exit if your AAPL position is 0 i.e. you own 0 stocks of AAPL. Again, exit point can be of your choice, but remember that exit point is the most crucial part of an algorithm because, without an exit point, the algo will keep on buying or selling.

if data['Buy'].item()==1:

while data['close'].item()<data['long_entry_point'].item() and account_balance()['balances']['total_cash']>=2000:

buy(5,symbol)

print('Long')

message="Mean-Reversion algo had a Long Signal and 5 of {} will be bought if cash is more than $2000".format(symbol)

sms_and_email('+16xxxxxxxx','123@abc.com',message)

elif data['Sell'].item()==1:

# Calculating the number of positions we hold for the given stock

my_positions=account_positions()

for k,v in my_positions.items():

if v['position']['symbol']==symbol:

symbol_position_qantity=v['position']['quantity']

while data['close']>data['sell_entry_point'] and symbol_position_qantity>=0:

sell(2,symbol)

print('Sell')

message="Mean-Reversion algo had a Sell Signal, position will be closed for {}".format(symbol)

email('123@abc.com',message)

One can clearly notice that we have called sms_and_email() while our algorithm is buying stocks and email() while selling the stocks. This shall help us to be stay updated on what our algorithm is doing. You can completely change the condition for receiving alerts and the information you receive via the alerts.

Hence, this is what the trade() function looks like:

def trade(symbol):



today=str(datetime.date.today())

data=analysis(symbol.upper())

data=data.loc[data['date']==today]

if data['Buy'].item()==1:

while data['close'].item()<data['long_entry_point'].item() and account_balance()['balances']['total_cash']>=2000:

buy(5,symbol)

print('Long')

message="Mean-Reversion algo had a Long Signal and 5 of {} will be bought if cash is more than $2000".format(symbol)

email('chetan@kloudtrader.com',message)

elif data['Sell'].item()==1:

# Calculating the number of positions we hold for the given stock

my_positions=account_positions()

for k,v in my_positions.items():

if v['position']['symbol']==symbol:

symbol_position_qantity=v['position']['quantity']

while data['close']>data['sell_entry_point'] and symbol_position_qantity>=0:

sell(2,symbol)

print('Sell')

message="Mean-Reversion algo had a Sell Signal, position will be closed for {}".format(symbol)

email('chetan@kloudtrader.com',message)

Note: When to buy/sell, what to buy/sell, how much to buy/sell is user-specific and does not reflect the decisions of the writer since this is for reference purposes.

And finally the main loop. We call it the main loop since this snippet of code enables the algorithm to continually trade throughout the trading day.

while intraday_status()['clock']['state']!='closed':

trade('AAPL')

This will ensure that it will when the market is open,meaning that the algorithm will remain dormant during pre-market and post-market hours. If you want to do after hours trading, feel free to change the code accordingly. Click here for documentation reference on intraday_status().

Finally, your main.py that contains a mean-reversion trading strategy will look like this:

#Mean Reversion Strategy in Python

from libkloudtrader.defaults import *

from libkloudtrader.equities.data import close_prices, intraday_status

from libkloudtrader.user import account_positions,account_balance

from libkloudtrader.alert_me import *

from libkloudtrader.analysis import ema

import datetime

import pandas as pd def analysis(symbol):

close_data=close_prices(symbol,'2018-01-01',datetime.date.today())

df=pd.DataFrame(close_data)

window=15

df['EMA']= ta.trend.ema(df['close'],n=window)

df['long_entry_point']=df['EMA']-(5/100)*df['EMA']

df['sell_entry_point']=df['EMA']+(5/100)*df['EMA']

df=df.iloc[window:]

df['Buy']=df.apply(lambda x : 1 if x['close']<x['EMA'] else 0,axis=1)

df['Sell']=df.apply(lambda x : 1 if x['close']>x['EMA'] else 0,axis=1)

return df def trade(symbol):



today=str(datetime.date.today())

data=analysis(symbol.upper())

data=data.loc[data['date']==today]

if data['Buy'].item()==1:

while data['close'].item()<data['long_entry_point'].item() and account_balance()['balances']['total_cash']>=2000:

buy(5,symbol)

print('Long')

message="Mean-Reversion algo had a Long Signal and 5 of {} will be bought if cash is more than $2000".format(symbol)

email('chetan@kloudtrader.com',message)

elif data['Sell'].item()==1:

# Calculating the number of positions we hold for the given stock

my_positions=account_positions()

for k,v in my_positions.items():

if v['position']['symbol']==symbol:

symbol_position_qantity=v['position']['quantity']

while data['close']>data['sell_entry_point'] and symbol_position_qantity>=0:

sell(2,symbol)

print('Sell')

message="Mean-Reversion algo had a Sell Signal, position will be closed for {}".format(symbol)

email('chetan@kloudtrader.com',message)



while intraday_status()['clock']['state']!='closed':

trade('AAPL')

After you have successfully completed your trading algorithm, you are ready to deploy it on Narwhal and trade in the U.S. equity market. Please follow our docs on getting started with libkloudtrader and Narwhal here.

Many more features like Paper trading, trading with other asset classes like Crypto, Derivatives, Forex, etc coming soon. Subscribe to our mailing list to keep yourself updated on the latest developments at KloudTrader.

This article is not intended to provide investment advice. This article is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory or other services by KloudTrader. KloudTrader makes no guarantees as to accuracy or completeness of the views expressed in this article. The views are subject to change and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.