Code Monkey home page Code Monkey logo

oanda-bot-python's Introduction

oanda-bot

PyPI License: MIT codecov Build Status PyPI - Python Version Downloads

oanda-bot is a python library for automated trading bot with oanda rest api on Python 3.6 and above.

Installation

$ pip install oanda-bot

Usage

basic run

from oanda_bot import Bot

class MyBot(Bot):
    def strategy(self):
        fast_ma = self.sma(period=5)
        slow_ma = self.sma(period=25)
        # golden cross
        self.sell_exit = self.buy_entry = (fast_ma > slow_ma) & (
            fast_ma.shift() <= slow_ma.shift()
        )
        # dead cross
        self.buy_exit = self.sell_entry = (fast_ma < slow_ma) & (
            fast_ma.shift() >= slow_ma.shift()
        )

MyBot(
    account_id='<your practice account id>',
    access_token='<your practice access token>',
).run()

basic backtest

from oanda_bot import Bot

class MyBot(Bot):
    def strategy(self):
        fast_ma = self.sma(period=5)
        slow_ma = self.sma(period=25)
        # golden cross
        self.sell_exit = self.buy_entry = (fast_ma > slow_ma) & (
            fast_ma.shift() <= slow_ma.shift()
        )
        # dead cross
        self.buy_exit = self.sell_entry = (fast_ma < slow_ma) & (
            fast_ma.shift() >= slow_ma.shift()
        )

MyBot(
    account_id='<your practice account id>',
    access_token='<your practice access token>',
).backtest()

basic report

from oanda_bot import Bot

Bot(
    account_id='<your practice account id>',
    access_token='<your practice access token>',
).report()

advanced run

from oanda_bot import Bot

class MyBot(Bot):
    def strategy(self):
        rsi = self.rsi(period=10)
        ema = self.ema(period=20)
        lower = ema - (ema * 0.001)
        upper = ema + (ema * 0.001)
        self.buy_entry = (rsi < 30) & (self.df.C < lower)
        self.sell_entry = (rsi > 70) & (self.df.C > upper)
        self.sell_exit = ema > self.df.C
        self.buy_exit = ema < self.df.C
        self.units = 1000 # currency unit (default=10000)
        self.take_profit = 50 # take profit pips (default=0 take profit none)
        self.stop_loss = 20 # stop loss pips (default=0 stop loss none)

MyBot(
    account_id='<your practice account id>',
    access_token='<your practice access token>',
    # trading environment (default=practice)
    environment='practice',
    # trading currency (default=EUR_USD)
    instrument='USD_JPY',
    # 1 minute candlesticks (default=D)
    granularity='M1',
    # trading time (default=Bot.SUMMER_TIME)
    trading_time=Bot.WINTER_TIME,
    # Slack notification when an error occurs
    slack_webhook_url='<your slack webhook url>',
    # Line notification when an error occurs
    line_notify_token='<your line notify token>',
    # Discord notification when an error occurs
    discord_webhook_url='<your discord webhook url>',
).run()

advanced backtest

from oanda_bot import Bot

class MyBot(Bot):
    def strategy(self):
        rsi = self.rsi(period=10)
        ema = self.ema(period=20)
        lower = ema - (ema * 0.001)
        upper = ema + (ema * 0.001)
        self.buy_entry = (rsi < 30) & (self.df.C < lower)
        self.sell_entry = (rsi > 70) & (self.df.C > upper)
        self.sell_exit = ema > self.df.C
        self.buy_exit = ema < self.df.C
        self.units = 1000 # currency unit (default=10000)
        self.take_profit = 50 # take profit pips (default=0 take profit none)
        self.stop_loss = 20 # stop loss pips (default=0 stop loss none)

MyBot(
    account_id='<your practice account id>',
    access_token='<your practice access token>',
    instrument='USD_JPY',
    granularity='S15', # 15 second candlestick
).backtest(from_date="2020-7-7", to_date="2020-7-13", filename="backtest.png")
total profit        3910.000
total trades         374.000
win rate              59.091
profit factor          1.115
maximum drawdown    4220.000
recovery factor        0.927
riskreward ratio       0.717
sharpe ratio           0.039
average return         9.787
stop loss              0.000
take profit            0.000

backtest.png

advanced report

from oanda_bot import Bot

Bot(
    account_id='<your practice account id>',
    access_token='<your practice access token>',
    instrument='USD_JPY',
    granularity='S15', # 15 second candlestick
).report(filename="report.png", days=-7) # from 7 days ago to now
total profit        -4960.000
total trades          447.000
win rate               59.284
profit factor          -0.887
maximum drawdown    10541.637
recovery factor        -0.471
riskreward ratio       -0.609
sharpe ratio           -0.043
average return        -10.319

report.png

live run

from oanda_bot import Bot

class MyBot(Bot):
    def atr(self, *, period: int = 14, price: str = "C"):
        a = (self.df.H - self.df.L).abs()
        b = (self.df.H - self.df[price].shift()).abs()
        c = (self.df.L - self.df[price].shift()).abs()

        df = pd.concat([a, b, c], axis=1).max(axis=1)
        return df.ewm(span=period).mean()

    def strategy(self):
        rsi = self.rsi(period=10)
        ema = self.ema(period=20)
        atr = self.atr(period=20)
        lower = ema - atr
        upper = ema + atr
        self.buy_entry = (rsi < 30) & (self.df.C < lower)
        self.sell_entry = (rsi > 70) & (self.df.C > upper)
        self.sell_exit = ema > self.df.C
        self.buy_exit = ema < self.df.C
        self.units = 1000

MyBot(
    account_id='<your live account id>',
    access_token='<your live access token>',
    environment='live',
    instrument='EUR_GBP',
    granularity='H12', # 12 hour candlesticks
    trading_time=Bot.WINTER_TIME,
    slack_webhook_url='<your slack webhook url>',
).run()

Supported indicators

  • Simple Moving Average 'sma'
  • Exponential Moving Average 'ema'
  • Moving Average Convergence Divergence 'macd'
  • Relative Strenght Index 'rsi'
  • Bollinger Bands 'bbands'
  • Market Momentum 'mom'
  • Stochastic Oscillator 'stoch'
  • Awesome Oscillator 'ao'

Getting started

For help getting started with OANDA REST API, view our online documentation.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

oanda-bot-python's People

Contributors

10mohi6 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oanda-bot-python's Issues

possible enhancement: add H:M:S to backtest code?

Hi,
Just wondering if there's the possibility to add hours, minutes, and (maybe not so much) seconds to the backtest function? Markets aren't really uniform throughout the whole day and it would be nice to be able to limit the backtest between certain times (e.g., 8:00 AM - 12:30 PM CST).
Cheers

profit targets and exits

Great little package ! thanks.
I don't understand one thing with the backtesting : If i set the take profit and stop loss, and set the buy and sell exits to False, should have only two outcomes, either it hits TP or SL. Does it also close the position when we also get a contrary position ? is there a option/fix/work around for it

bbands

Goodmorning,

My name is Benjamin, Thanks for this wonderful code, it works nicely! I'm having issues with implementing the bbands into the strategy. How can I for instance do a self.buy_entry when the price moves under the lower band? I figured it must be something like

self.buy_entry = self.df.C < mean - (std * band)

I found:

return mean + (std * band), mean, mean - (std * band)

I assume these are the three lines (upper band, mean and lowerband), but I can't figure out how to call these in the backtest or run?

Can you help? Thanks!

Benjamin

Calculation precision

Hey team, I hope all of you are doing well in these times.

So I have a question, related to calculation precision. I am not that knowledgeable with Python, so I cannot propose a concrete solution.

The issue is that for calculation as a type float is being used as a type, which leads to unstable calculations because of decimals.
I think this can pose a really big issue and is a no-go for us to use this. When decimals are being calculated and everything depends on the floating-point, something else should be used. Because it really depends on which CPU is the machine using, and what is the state of that CPU.

In the Java world, the solution is BigDecimal or a custom implementation.

For an example

bot = Bot(
    account_id='account-id',
    access_token='access-token',
    granularity='D',
    instrument='EUR_USD',
    environment='practice'
)
print(bot._candles(count='6'))

print(bot.rsi(period=5))

Prints a different result every time.

Is there a plan to resolve this in the near future?

EDIT:
Also, this would apply to all calculations inside the app with float as a type

Code hands on backtest when dates are added.

Hi there,

As the title says, it hangs, never finishes, when I use this:

from oanda_bot import Bot

class MyBot(Bot):
    def strategy(self):
        rsi = self.rsi(period=5)
        ema = self.ema(period=10)
        lower = ema - (ema * 0.001)
        upper = ema + (ema * 0.001)
        self.buy_entry = (rsi < 40) & (self.df.C < lower)
        self.sell_entry = (rsi > 60) & (self.df.C > upper)
        self.sell_exit = ema > self.df.C
        self.buy_exit = ema < self.df.C
        self.units = 1000 # currency unit (default=10000)
        self.take_profit = 20 # take profit pips (default=0 take profit none)
        self.stop_loss = 10 # stop loss pips (default=0 stop loss none)
        

MyBot(
    account_id='<acc id>',
    access_token='<token>',
    instrument='USD_JPY',
    granularity='H1', # 1 hour candlestick
).backtest(from_date="2020-12-31", to_date="2021-1-31", filename="backtest.png")

When I CTRL+C, it returns this:

Traceback (most recent call last):
  File "F:\...\advancedBacktest.py", line 18, in <module>
    MyBot(
  File "F:\Python3\...\oanda_bot.py", line 380, in backtest
    self._candles(from_date=from_date, to_date=to_date)
  File "F:\Python3\...\oanda_bot.py", line 125, in _candles
    time.sleep(0.5)
KeyboardInterrupt

If I run without time constraints, it runs to completion in a matter of seconds.
Any ideas what the issue might be?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.