<aside> ❗ Tip: Please check from time to time to stay updated with the reference and documentation
</aside>
/
PEMBE.io is an algorithmic trading platform for quantitative traders. We empower quants, developers and traders to go independent by providing them trading platform to design, create, optimize, backtest, paper trading and live-trading strategies. You just need some basic python language skills to develop your own algorithmic trading strategies.
We tried to provide you the complete value chain of developing trading strategies. Some features are not live, but will be in the near future. But the idea is to create with python code to set all the rules for your trading plan. Choose the trading pair of your cryptocurrency i.e. BTCUSDT, select time period, the amount of allocated capital, your candle size, your order size and hit “run backtest” and we generate for you a performance sheet with all the KPIs you need to assess if the strategy is worth optimizing or not. Next step is paper trading and after then switch to live-trading on different crypto exchanges.
The core of the PEMBEs market data API is historical OHLCV data. Even if the OHLCV are self-explanatory. Here is a brief explanation of the individual parameters:
<aside> ❗ Currently we don’t have activated our paid subscription model for the market data API. But you need a personal API key to pull the desired data from our data servers.
</aside>
Type | Explanation |
---|---|
Open | Price of asset at the beginning of the respective time period |
High | Highest asset price within the respective time period |
Low | Lowest asset price within the respective time period |
Close | Price of asset at the end of the respective time period |
Volume | Aggregated volume (number of trades) of asset for the respective time period |
The OHLCV data depends on the selected timeframe. 15 minutes candle size (=candlestick) data is subject to a timeframe of 15 minutes. The time difference between the open of the candle size period and the close is then 15 minutes. The high value describes the highest value of the 15 minute period. The low value describes the lowest value of the 15 minute period.
The following timeframes are possible for different candly-size periods:
m = minutes | h = hours | d = days | w = weeks |
---|---|---|---|
1m | 1h | 1d | 1w |
5m | 2h | 3d | |
15m | 4h | ||
30m | 6h | ||
8h | |||
12h |
m | The time series is aggregated on a per-minute basis |
---|---|
h | The time series is aggregated on a hourly basis |
d | The time series is aggregated on a daily basis |
w | The time series is aggregated on a weekly basis |
For longer periods, large values such as day are often appropriate. minutes is often suitable for shorter periods of time. The time series length can be set with a date range. Time series of up to 5 years are possible. depending on the selected subscription. The date format can be represented as follows:
startdate = 2023-02-15
enddate = 2023-02-19
In order to be able to assign the indiviual candles chronologically, a timestamp is always given in the response output at the beginning of each candle period. This like this:
"2023-03-14T00:00:00"
BTCUSDT | ADAEUR | MATICUSDT | UNIEUR |
---|---|---|---|
BTCEUR | BNBUSDT | MATICEUR | DOTUSDT |
ETHUSDT | BNBEUR | SOLUSDT | DOTEUR |
ETHEUR | XRPUSDT | SOLEUR | LTCUSDT |
ADAUSDT | XRPEUR | UNIUSDT | LTCEUR |
To specify your request, you can find a summary of all options under “Parameters”.
GET <https://backend.pembe.io/api/v1/gethistoricaldata>
Parameters | Type | Description | Values |
---|---|---|---|
Coinpair | string |
usable coinpairs | {BTCUSDT, BTCEUR, ETHUSDT, ETHEUR, ADAUSDT, ADAEUR, BNBUSDT, BNBEUR, XRPUSDT, XRPEUR, MATICUSDT, MATICEUR, SOLUSDT, SOLEUR,UNIUSDT, UNIEUR, DOTUSDT, DOTEUR, LTCUSDT, LTCEUR} |
Candlesize | string |
type of candlestick patterns | {1m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w} |
Startdate/Enddate | string |
YEAR-MONTH-DAYY / YYYY-MM-DD |
Example; startdate= 2023-02-15, enddate = 2023-02-19 |
<aside> ❗ Depends on different packages
Note that the possible coinpairs, candlesizes and length of the time series depends on the package you have subscribed to!
</aside>
The response is returned in a Json format. The following is an example Json response for BTCUSDT
on a daily basis.
{
"2021-03-14T00:00:00", "61091.75", "61480", "61089.98", "61444.77", "1111.279224",
"2021-03-15T00:00:00", "61092.80", "61485", "61089.79", "61444.91", "1111.279553",
"2021-03-16T00:00:00", "61092.88", "61585", "61089.39", "61444.92", "1111.279545",
"2021-03-17T00:00:00", "61092.89", "61675", "61089.49", "61444.93", "1111.279555",
"2021-03-18T00:00:00", "61092.99", "61765", "61089.69", "61444.64", "1111.279665",
"2021-03-19T00:00:00", "61062.99", "61755", "61089.89", "61444.74", "1111.279665",
"2021-03-20T00:00:00", "61072.99", "61745", "61089.99", "61444.84", "1111.279775",
.................
.................
}
The following table contains the description of the individual return values. The chronology always remains the same. The first index is always the date followed by oben, high, low, close and volume:
Field | Description |
---|---|
datetime | Start time of the candle stick cycle |
open | Opening price of the candle stick |
high | Highest price of the candle stick |
low | Lowest price of the candle stick |
close | Closing price of the candle stick |
volume | Transaction volume (#number of trades in a given time period) |
The following is a list of the error returns from the API and the explanation of each error. (tbc)
Error Type | Description |
---|---|
Error : No credentials found in header |
The API key is not provided in the HTTPS header, cannot be decoded by the backend, or the API Key does not exist. You can find an example of how the keys are optimally transmitted in the Chapter: Authentication |
Error : API key or API secret is invalid |
You do not have a valid API Key or API Secret. Check the correctness of your keys in the 'API-KEY' area in the APP: API-KEY-Area or create a new one there. If you have further problems, please contact our support: [email protected] or check our discord server |
Error : Not logged in |
This error appears when the account is not actively logged into the frontend. |
Error : Critical error |
An error occurred in the backend. This is not your fault. We will take care of it. |
API without specific values:
<https://backend.pembe.io/api/v1/gethistoricaldata/{coinpair}/{candlesize}/{startdate}/{enddate}>
Example of Bitcoin/USDT data for two years with the candle size on a daily basis
{coinpair} = BTCUSDT
{candlesize} = 1d
{startdate} = 2023-02-15
{enddate} = 2023-02-19
API-Call with example values:
<https://backend.pembe.io/api/v1/gethistoricaldata/BTCUSDT/1d/2023-02-15/2023-02-19>
# Example with Python
import requests
url = "<https://backend.pembe.io/api/v1/gethistoricaldata/BTCUSDT/1d/2023-02-15/2023-02-19>"
# The client should pass the API credentials in the headers
headers = {
'Content-Type': 'application/json',
'API-Key': 'FyqP5fzyOYUNfkJTVGTlZK4tdsLfsBC8HqHx4efrqRBe2idCxz58vUq6jWVtjmID', # INSERT YOUR API-KEY
'API-Secret' : 'e4da7fbd-f1b0-4b3c-9956-3ceda8a5f016-dummy' # INSERT YOUR API-SECRET
}
response = requests.get(url, headers=headers)
print(response.text)
The personal API key can be generated and deleted in the 'API Keys' area of the dashboard: https://app.pembe.io/dashboard/apikeys. Then connect to the API, you should use the example code above as a guide. Copy your personal API-Key + Secret into the headers to start the connection. The API url can be set up like in example above described to pull the desired data.
<aside> ❗ Our strategy-editor is the heart of PEMBE application.
The special thing about our application is the following: we use native Python code that is executed directly in the browser and we try to avoid various wrappers or pseudo script languages so that the user can start using the application directly.
</aside>
The strategy-editor has on the left side the well-known editor surface and on the right side some backtest settings to adjust the strategy which you want to create. Just as a small introduction, we will cover this topic later, we are using the open source Python library of the powerfull backtrader. All functions of backtrader you can find at the official backtrader documentation. Check here: https://backtrader.com/docu/
<aside> ❗ The first class is always pre-defined in the strategy-editor!
Don’t change the name of the class. We have some sample strategies, where it looks like you can also change it. No you can’t. Sorry mate!
</aside>
class Testclass_uWuWYxpq(backtrader.Strategy):
This is for simplification and rapid development of the strategy. It is also possible to insert the backtrader indicators directly after the class (not before!). The first line in the editor should therefore not be changed. We have also removed everything related the class cerebro
to makes things easier for you.
Before we dive in, a short description how backtrader is working and what we have developed. We want to describe the concepts of the platform. It tries to gather information bits whcih can be useful in using and unerstanding the platform.
Before Starting
You don’t need to import all the backtrader statements in your trading strategies, this will be provided from our platform side.
import backtrader as bt
import backtrader.indicators as btind
import backtrader.feeds as btfeeds
The basis of the work with the platform will be done with Strategies. To get the full view of the concepts and how these will get passed to Data Feeds, you can check here https://backtrader.com/docu/concepts
class MyStrategy(bt.Strategy):
params = dict(period=20)
def __init__(self):
sma = btind.SimpleMovingAverage(self.datas[0], period=self.params.period)
...
# everything related cerebro and data feeds will be handled from our side, all the cerebro statements you don't need on PEMBE.
cerebro = bt.Cerebro()
...
data = btfeeds.MyFeed(...)
cerebro.adddata(data)
...
cerebro.addstrategy(MyStrategy, period=30)
...
The beginning of the strategy. The concept is described in this Backtrader documentary section: https://backtrader.com/docu/strategy/
__init__
start
prenext
next
None
stop
class SMA_10_50(backtrader.Strategy):
# don't change the first line. only copy the code below the class:
### indicators
def __init__(self):
ma_fast = backtrader.ind.SMA(period=5)
ma_mid = backtrader.ind.SMA(period=8)
ma_slow = backtrader.ind.SMA(period=13)
### Conditions
self.crossover = backtrader.ind.CrossOver(ma_fast, ma_slow, ma_mid)
### Orders
def next(self):
if not self.position:
if self.crossover > 0:
self.buy()
elif self.crossover < 0:
self.close()
The first line again defines the class in the same concept as described in “Getting Started”
class SMA_10_50(backtrader.Strategy):
The easiest way to explain the concept is with a simple strategy. As you can see there is no any cerebro or data statements necessary. You choose your data feeds from the right setting panel on the strategy-editor page.
Every strategy beginns with the following:
def __init__(self):
### indicators
def __init__(self):
ma_fast = backtrader.ind.SMA(period=5)
ma_mid = backtrader.ind.SMA(period=8)
ma_slow = backtrader.ind.SMA(period=13)
### Conditions
self.crossover = backtrader.ind.CrossOver(ma_fast, ma_slow, ma_mid)