Oandatest no attribute 'contractdetails'
-
Hello Dro,
I' m trying to use the code Oandatest.py but that doesn't work I have the following error:File "C:/samples/oandatest/oandatest.py", line 168, in start if self.data0.contractdetails is not None: File "C:\backtrader\lineseries.py", line 429, in __getattr__ return getattr(self.lines, name) AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'contractdetails'
I have install Oanda.py it works indepandently from BT and entered the parameters : acount , practice and token.
Do you have an idea how to solve this issue ? -
Without some code it is really difficult to understand why things may go wrong.
There are two random guesses that can be made by looking at the actual reported error:
- The actual error code seems to indicate that
data0
is not an actualOandaData
or
- The requested timeframe/compression pair is not supported and the data feed is bailing out from creating a
contractdetails
attribute. This is reported in as aNOTSUPPORTED_TF
data notification.
The sample is not coded with full robustness, because it is a sample.
- The actual error code seems to indicate that
-
re: Oandatest no attribute 'contractdetails'
Hello thanks for the answer. Do you know how I can select the right dataframe supported ?
I'm sorry for the code it is below. here this the paramaters I used--token mytoken --account myaccount --data0 EUR_USD
Thank you very much for your help.
# Copyright (C) 2015,2016 Daniel Rodriguez # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. ############################################################################### from future import (absolute_import, division, print_function, unicode_literals) import oandapy import argparse import datetime # The above could be sent to an independent module import backtrader as bt from backtrader.utils import flushfile # win32 quick stdout flushing StoreCls = bt.stores.OandaStore DataCls = bt.feeds.OandaData BrokerCls = bt.brokers.OandaBroker class TestStrategy(bt.Strategy): params = dict( smaperiod=5, trade=False, stake=10, exectype=bt.Order.Market, stopafter=0, valid=None, cancel=0, donotcounter=False, sell=False, ) def __init__(self): # To control operation entries self.orderid = list() self.order = None self.counttostop = 0 self.datastatus = 0 # Create SMA on 2nd data self.sma = bt.indicators.MovAv.SMA(self.data, period=self.p.smaperiod) print('--------------------------------------------------') print('Strategy Created') print('--------------------------------------------------') def notify_data(self, data, status, *args, **kwargs): print('*' * 5, 'DATA NOTIF:', data._getstatusname(status), *args) if status == data.LIVE: self.counttostop = self.p.stopafter self.datastatus = 1 def notify_store(self, msg, *args, **kwargs): print('*' * 5, 'STORE NOTIF:', msg) def notify_order(self, order): if order.status in [order.Completed, order.Cancelled, order.Rejected]: self.order = None print('-' * 50, 'ORDER BEGIN', datetime.datetime.now()) print(order) print('-' * 50, 'ORDER END') def notify_trade(self, trade): print('-' * 50, 'TRADE BEGIN', datetime.datetime.now()) print(trade) print('-' * 50, 'TRADE END') def prenext(self): self.next(frompre=True) def next(self, frompre=False): txt = list() txt.append('Data0') txt.append('%04d' % len(self.data0)) dtfmt = '%Y-%m-%dT%H:%M:%S.%f' txt.append('{:f}'.format(self.data.datetime[0])) txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt)) txt.append('{:f}'.format(self.data.open[0])) txt.append('{:f}'.format(self.data.high[0])) txt.append('{:f}'.format(self.data.low[0])) txt.append('{:f}'.format(self.data.close[0])) txt.append('{:6d}'.format(int(self.data.volume[0]))) txt.append('{:d}'.format(int(self.data.openinterest[0]))) txt.append('{:f}'.format(self.sma[0])) print(', '.join(txt)) if len(self.datas) > 1 and len(self.data1): txt = list() txt.append('Data1') txt.append('%04d' % len(self.data1)) dtfmt = '%Y-%m-%dT%H:%M:%S.%f' txt.append('{}'.format(self.data1.datetime[0])) txt.append('%s' % self.data1.datetime.datetime(0).strftime(dtfmt)) txt.append('{}'.format(self.data1.open[0])) txt.append('{}'.format(self.data1.high[0])) txt.append('{}'.format(self.data1.low[0])) txt.append('{}'.format(self.data1.close[0])) txt.append('{}'.format(self.data1.volume[0])) txt.append('{}'.format(self.data1.openinterest[0])) txt.append('{}'.format(float('NaN'))) print(', '.join(txt)) if self.counttostop: # stop after x live lines self.counttostop -= 1 if not self.counttostop: self.env.runstop() return if not self.p.trade: return if self.datastatus and not self.position and len(self.orderid) < 1: if not self.p.sell: # price = round(self.data0.close[0] * 0.90, 2) price = self.data0.close[0] - 0.005 self.order = self.buy(size=self.p.stake, exectype=self.p.exectype, price=price, valid=self.p.valid) else: # price = round(self.data0.close[0] * 1.10, 4) price = self.data0.close[0] - 0.05 self.order = self.sell(size=self.p.stake, exectype=self.p.exectype, price=price, valid=self.p.valid) self.orderid.append(self.order) elif self.position and not self.p.donotcounter: if self.order is None: if not self.p.sell: self.order = self.sell(size=self.p.stake // 2, exectype=bt.Order.Market, price=self.data0.close[0]) else: self.order = self.buy(size=self.p.stake // 2, exectype=bt.Order.Market, price=self.data0.close[0]) self.orderid.append(self.order) elif self.order is not None and self.p.cancel: if self.datastatus > self.p.cancel: self.cancel(self.order) if self.datastatus: self.datastatus += 1 """ def start(self): if self.data0.contractdetails is not None: print('-- Contract Details:') print(self.data0.contractdetails) header = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume', 'OpenInterest', 'SMA'] print(', '.join(header)) self.done = False """ def runstrategy(): args = parse_args() # Create a cerebro cerebro = bt.Cerebro() storekwargs = dict( token="mytoken", account="myaccount", practice="practice" ) if not args.no_store: store = StoreCls(**storekwargs) if args.broker: if args.no_store: broker = BrokerCls(**storekwargs) else: broker = store.getbroker() cerebro.setbroker(broker) timeframe = bt.TimeFrame.TFrame(args.timeframe) # Manage data1 parameters tf1 = args.timeframe1 tf1 = bt.TimeFrame.TFrame(tf1) if tf1 is not None else timeframe cp1 = args.compression1 cp1 = cp1 if cp1 is not None else args.compression if args.resample or args.replay: datatf = datatf1 = bt.TimeFrame.Ticks datacomp = datacomp1 = 1 else: datatf = timeframe datacomp = args.compression datatf1 = tf1 datacomp1 = cp1 fromdate = None if args.fromdate: dtformat = '%Y-%m-%d' + ('T%H:%M:%S' * ('T' in args.fromdate)) fromdate = datetime.datetime.strptime(args.fromdate, dtformat) DataFactory = DataCls if args.no_store else store.getdata datakwargs = dict( timeframe=datatf, compression=datacomp, qcheck=args.qcheck, historical=args.historical, fromdate=fromdate, bidask=args.bidask, useask=args.useask, backfill_start=not args.no_backfill_start, backfill=not args.no_backfill, tz=args.timezone ) if args.no_store and not args.broker: # neither store nor broker datakwargs.update(storekwargs) # pass the store args over the data data0 = DataFactory(dataname=args.data0, **datakwargs) data1 = None if args.data1 is not None: if args.data1 != args.data0: datakwargs['timeframe'] = datatf1 datakwargs['compression'] = datacomp1 data1 = DataFactory(dataname=args.data1, **datakwargs) else: data1 = data0 rekwargs = dict( timeframe=timeframe, compression=args.compression, bar2edge=not args.no_bar2edge, adjbartime=not args.no_adjbartime, rightedge=not args.no_rightedge, takelate=not args.no_takelate, ) if args.replay: cerebro.replaydata(dataname=data0, **rekwargs) if data1 is not None: rekwargs['timeframe'] = tf1 rekwargs['compression'] = cp1 cerebro.replaydata(dataname=data1, **rekwargs) elif args.resample: cerebro.resampledata(dataname=data0, **rekwargs) if data1 is not None: rekwargs['timeframe'] = tf1 rekwargs['compression'] = cp1 cerebro.resampledata(dataname=data1, **rekwargs) else: cerebro.adddata(data0) if data1 is not None: cerebro.adddata(data1) if args.valid is None: valid = None else: valid = datetime.timedelta(seconds=args.valid) # Add the strategy cerebro.addstrategy(TestStrategy, smaperiod=args.smaperiod, trade=args.trade, exectype=bt.Order.ExecType(args.exectype), stake=args.stake, stopafter=args.stopafter, valid=valid, cancel=args.cancel, donotcounter=args.donotcounter, sell=args.sell) # Live data ... avoid long data accumulation by switching to "exactbars" cerebro.run(exactbars=args.exactbars) if args.exactbars < 1: # plotting is possible if args.plot: pkwargs = dict(style='line') if args.plot is not True: # evals to True but is not True npkwargs = eval('dict(' + args.plot + ')') # args were passed pkwargs.update(npkwargs) cerebro.plot(**pkwargs) def parse_args(pargs=None): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Test Oanda integration') parser.add_argument('--exactbars', default=1, type=int, required=False, action='store', help='exactbars level, use 0/-1/-2 to enable plotting') parser.add_argument('--stopafter', default=0, type=int, required=False, action='store', help='Stop after x lines of LIVE data') parser.add_argument('--no-store', required=False, action='store_true', help='Do not use the store pattern') parser.add_argument('--debug', required=False, action='store_true', help='Display all info received from source') parser.add_argument('--token', default="mytoken", required=True, action='store', help='Access token to use') parser.add_argument('--account', default=None, required=True, action='store', help='Account identifier to use') parser.add_argument('--live', default=None, required=False, action='store', help='Go to live server rather than practice') parser.add_argument('--qcheck', default=0.5, type=float, required=False, action='store', help=('Timeout for periodic ' 'notification/resampling/replaying check')) parser.add_argument('--data0', default='EUR_USD', required=True, action='store', help='data 0 into the system') parser.add_argument('--data1', default=None, required=False, action='store', help='data 1 into the system') parser.add_argument('--timezone', default=None, required=False, action='store', help='timezone to get time output into (pytz names)') parser.add_argument('--bidask', default=None, required=False, action='store_true', help='Use bidask ... if False use midpoint') parser.add_argument('--useask', default=None, required=False, action='store_true', help='Use the "ask" of bidask prices/streaming') parser.add_argument('--no-backfill_start', required=False, action='store_true', help='Disable backfilling at the start') parser.add_argument('--no-backfill', required=False, action='store_true', help='Disable backfilling after a disconnection') parser.add_argument('--historical', required=False, action='store_true', help='do only historical download') parser.add_argument('--fromdate', required=False, action='store', help=('Starting date for historical download ' 'with format: YYYY-MM-DD[THH:MM:SS]')) parser.add_argument('--smaperiod', default=20, type=int, required=False, action='store', help='Period to apply to the Simple Moving Average') pgroup = parser.add_mutually_exclusive_group(required=False) pgroup.add_argument('--replay', required=False, action='store_true', help='replay to chosen timeframe') pgroup.add_argument('--resample', required=False, action='store_true', help='resample to chosen timeframe') parser.add_argument('--timeframe', default=bt.TimeFrame.Names[0], choices=bt.TimeFrame.Names, required=False, action='store', help='TimeFrame for Resample/Replay') parser.add_argument('--compression', default=1, type=int, required=False, action='store', help='Compression for Resample/Replay') parser.add_argument('--timeframe1', default=None, choices=bt.TimeFrame.Names, required=False, action='store', help='TimeFrame for Resample/Replay - Data1') parser.add_argument('--compression1', default=None, type=int, required=False, action='store', help='Compression for Resample/Replay - Data1') parser.add_argument('--no-takelate', required=False, action='store_true', help=('resample/replay, do not accept late samples')) parser.add_argument('--no-bar2edge', required=False, action='store_true', help='no bar2edge for resample/replay') parser.add_argument('--no-adjbartime', required=False, action='store_true', help='no adjbartime for resample/replay') parser.add_argument('--no-rightedge', required=False, action='store_true', help='no rightedge for resample/replay') parser.add_argument('--broker', required=False, action='store_true', help='Use Oanda as broker') parser.add_argument('--trade', required=False, action='store_true', help='Do Sample Buy/Sell operations') parser.add_argument('--sell', required=False, action='store_true', help='Start by selling') parser.add_argument('--donotcounter', required=False, action='store_true', help='Do not counter the 1st operation') parser.add_argument('--exectype', default=bt.Order.ExecTypes[0], choices=bt.Order.ExecTypes, required=False, action='store', help='Execution to Use when opening position') parser.add_argument('--stake', default=10, type=int, required=False, action='store', help='Stake to use in buy operations') parser.add_argument('--valid', default=None, type=float, required=False, action='store', help='Seconds to keep the order alive (0 means DAY)') parser.add_argument('--cancel', default=0, type=int, required=False, action='store', help=('Cancel a buy order after n bars in operation,' ' to be combined with orders like Limit')) # Plot options parser.add_argument('--plot', '-p', nargs='?', required=False, metavar='kwargs', const=True, help=('Plot the read data applying any kwargs passed\n' '\n' 'For example (escape the quotes if needed):\n' '\n' ' --plot style="candle" (to plot candles)\n')) if pargs is not None: return parser.parse_args(pargs) return parser.parse_args() if name == 'main': runstrategy()
-
from your clues I found out the time frame didn't work if I g below the Minutes.
Ticks didn't works and seconds didn't work.
with minutes I have the following error message:-------------------------------------------------- Strategy Created -------------------------------------------------- Datetime, Open, High, Low, Close, Volume, OpenInterest, SMA ***** DATA NOTIF: NOTSUBSCRIBED Process finished with exit code 0
when I use Oandpy without BT It works and I don't need to specify the Account the token is enough.
do you know why TIcks and seconds did not work ?I sorry can you please erase , the topic I created by error it was supposed to be the answer of this topic.
Thank you very much
oanda = oandapy.API(environment="practice", access_token="mytoken ") response = oanda.get_prices(instruments="EUR_USD") prices = response.get("prices") asking_price = prices[0].get("ask") marketdata= oanda.get_history(instrument="EUR_USD",granularity="M1",candleFormat="midpoint", start=startdt, end=enddt) candle=marketdata['candles'] print (type(candle))
-
The data feed documentation says:
This data feed supports only this mapping of ``timeframe`` and ``compression``, which comply with the definitions in the OANDA API Developer's Guid:: (TimeFrame.Seconds, 5): 'S5', (TimeFrame.Seconds, 10): 'S10', (TimeFrame.Seconds, 15): 'S15', (TimeFrame.Seconds, 30): 'S30', (TimeFrame.Minutes, 1): 'M1', (TimeFrame.Minutes, 2): 'M3', (TimeFrame.Minutes, 3): 'M3', (TimeFrame.Minutes, 4): 'M4', (TimeFrame.Minutes, 5): 'M5', (TimeFrame.Minutes, 10): 'M5', (TimeFrame.Minutes, 15): 'M5', (TimeFrame.Minutes, 30): 'M5', (TimeFrame.Minutes, 60): 'H1', (TimeFrame.Minutes, 120): 'H2', (TimeFrame.Minutes, 180): 'H3', (TimeFrame.Minutes, 240): 'H4', (TimeFrame.Minutes, 360): 'H6', (TimeFrame.Minutes, 480): 'H8', (TimeFrame.Days, 1): 'D', (TimeFrame.Weeks, 1): 'W', (TimeFrame.Months, 1): 'M',
That means that
(Minutes, 1)
is supported if you only specified--timeframe Minutes
. If you specified--timeframe Seconds
, that implies acompression
of1
and it is not supported. Those limits are specified here:Yes, one can receive ticks with the Streaming API (which backtrader uses to build subsequent bars in real-time), but backfilling wouldn't then be possible.
-
This is a run of the sample right now (with
account
andtoken
changed)$ ./oandatest.py --account 0000000 --token A-B --data0 EUR_USD --timeframe Minutes -------------------------------------------------- Strategy Created -------------------------------------------------- -- Contract Details: {u'pip': u'0.0001', u'instrument': u'EUR_USD', u'maxTradeUnits': 10000000, u'displayName': u'EUR/USD'} Datetime, Open, High, Low, Close, Volume, OpenInterest, SMA ***** DATA NOTIF: DELAYED Data0, 0001, 736326.863194, 2016-12-28T20:43:00.000000, 1.041095, 1.041100, 1.041070, 1.041100, 7, 0, nan Data0, 0002, 736326.863889, 2016-12-28T20:44:00.000000, 1.041080, 1.041145, 1.041055, 1.041105, 17, 0, nan Data0, 0003, 736326.864583, 2016-12-28T20:45:00.000000, 1.041115, 1.041205, 1.041110, 1.041110, 11, 0, nan Data0, 0004, 736326.865278, 2016-12-28T20:46:00.000000, 1.041070, 1.041070, 1.040885, 1.040920, 13, 0, nan Data0, 0005, 736326.865972, 2016-12-28T20:47:00.000000, 1.040895, 1.040925, 1.040895, 1.040905, 5, 0, 1.041028 ... ... ... Data0, 0500, 736327.236806, 2016-12-29T05:41:00.000000, 1.045880, 1.045880, 1.045880, 1.045880, 1, 0, 1.045891 ***** DATA NOTIF: LIVE Data0, 0501, 736327.236821, 2016-12-29T05:41:01.375075, 1.045800, 1.045800, 1.045800, 1.045800, 0, 0, 1.045871 ... This is with a standard `Oanda` account with no special permissions whatsoever. With the default settings the sample uses the `practice` server.
-
Hello thank you for your response:
I took the sample and used the same parameters as you. except my account and my tokenI still have :
-------------------------------------------------- Strategy Created -------------------------------------------------- Datetime, Open, High, Low, Close, Volume, OpenInterest, SMA ***** DATA NOTIF: NOTSUBSCRIBED
Process finished with exit code 0
However when I import data and use the rest API of oanda I didn't need to specify the account and it work anyway.
I can receive historical data.
I use a demo account. -
No contract is being returned for your request and hence the answer:
NOT_SUBSCRIBED
Unless it would be the obvious (pointed out in the
README
)Oanda (needs oandapy) (REST API Only - v20 does not support streaming)
-
And of course the
token
is not needed to access the data. But the sample is also ready fortrading
and that's why it requires the token.You can remove that limitation in the sample.
-
@backtrader
Hello Dro,
I'm trying to use the sample oandatest.py but I have this error message.
"
traceback (most recent call last):
File "C:/Users/demo/PycharmProjects/oandatest.py", line 31, in <module>
StoreCls = bt.stores.OandaStore
AttributeError: 'module' object has no attribute 'OandaStore'
"I use the last version of backtrader and I have installed ondapyV20
I use the token and account name not the account number .
My account is a V20 type.I utilise the last version of the sample oandatest.py.
do you have any idea how to make this sample works ? did anyone had the same problem ?
-
@backtrader
please forget the my question : V20 is not supported with ondatest.py I need to ask the support for a oldversion account. -
@backtrader
I have asked for a legacy account . at the end of the year legacy account wont access the api service anymore.
I try with the legacy account (2121212 )here the code :
from future import (absolute_import, division, print_function,
unicode_literals)import argparse
import datetimeThe above could be sent to an independent module
import backtrader as bt
from backtrader.utils import flushfile # win32 quick stdout flushingStoreCls = bt.stores.OandaStore
DataCls = bt.feeds.OandaData
#BrokerCls = bt.brokers.OandaBrokerclass TestStrategy(bt.Strategy):
params = dict(
smaperiod=5,
trade=False,
stake=10,
exectype=bt.Order.Market,
stopafter=0,
valid=None,
cancel=0,
donotcounter=False,
sell=False,
usebracket=False,
)def __init__(self): # To control operation entries self.orderid = list() self.order = None self.counttostop = 0 self.datastatus = 0 # Create SMA on 2nd data self.sma = bt.indicators.MovAv.SMA(self.data, period=self.p.smaperiod) print('--------------------------------------------------') print('Strategy Created') print('--------------------------------------------------') def notify_data(self, data, status, *args, **kwargs): print('*' * 5, 'DATA NOTIF:', data._getstatusname(status), *args) if status == data.LIVE: self.counttostop = self.p.stopafter self.datastatus = 1 def notify_store(self, msg, *args, **kwargs): print('*' * 5, 'STORE NOTIF:', msg) def notify_order(self, order): if order.status in [order.Completed, order.Cancelled, order.Rejected]: self.order = None print('-' * 50, 'ORDER BEGIN', datetime.datetime.now()) print(order) print('-' * 50, 'ORDER END') def notify_trade(self, trade): print('-' * 50, 'TRADE BEGIN', datetime.datetime.now()) print(trade) print('-' * 50, 'TRADE END') def prenext(self): self.next(frompre=True) def next(self, frompre=False): txt = list() txt.append('Data0') txt.append('%04d' % len(self.data0)) dtfmt = '%Y-%m-%dT%H:%M:%S.%f' txt.append('{:f}'.format(self.data.datetime[0])) txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt)) txt.append('{:f}'.format(self.data.open[0])) txt.append('{:f}'.format(self.data.high[0])) txt.append('{:f}'.format(self.data.low[0])) txt.append('{:f}'.format(self.data.close[0])) txt.append('{:6d}'.format(int(self.data.volume[0]))) txt.append('{:d}'.format(int(self.data.openinterest[0]))) txt.append('{:f}'.format(self.sma[0])) print(', '.join(txt)) if len(self.datas) > 1 and len(self.data1): txt = list() txt.append('Data1') txt.append('%04d' % len(self.data1)) dtfmt = '%Y-%m-%dT%H:%M:%S.%f' txt.append('{}'.format(self.data1.datetime[0])) txt.append('%s' % self.data1.datetime.datetime(0).strftime(dtfmt)) txt.append('{}'.format(self.data1.open[0])) txt.append('{}'.format(self.data1.high[0])) txt.append('{}'.format(self.data1.low[0])) txt.append('{}'.format(self.data1.close[0])) txt.append('{}'.format(self.data1.volume[0])) txt.append('{}'.format(self.data1.openinterest[0])) txt.append('{}'.format(float('NaN'))) print(', '.join(txt)) if self.counttostop: # stop after x live lines self.counttostop -= 1 if not self.counttostop: self.env.runstop() return if not self.p.trade: return if self.datastatus and not self.position and len(self.orderid) < 1: if not self.p.usebracket: if not self.p.sell: # price = round(self.data0.close[0] * 0.90, 2) price = self.data0.close[0] - 0.005 self.order = self.buy(size=self.p.stake, exectype=self.p.exectype, price=price, valid=self.p.valid) else: # price = round(self.data0.close[0] * 1.10, 4) price = self.data0.close[0] - 0.05 self.order = self.sell(size=self.p.stake, exectype=self.p.exectype, price=price, valid=self.p.valid) else: print('USING BRACKET') price = self.data0.close[0] - 0.05 self.order, _, _ = self.buy_bracket(size=self.p.stake, exectype=bt.Order.Market, price=price, stopprice=price - 0.10, limitprice=price + 0.10, valid=self.p.valid) self.orderid.append(self.order) elif self.position and not self.p.donotcounter: if self.order is None: if not self.p.sell: self.order = self.sell(size=self.p.stake // 2, exectype=bt.Order.Market, price=self.data0.close[0]) else: self.order = self.buy(size=self.p.stake // 2, exectype=bt.Order.Market, price=self.data0.close[0]) self.orderid.append(self.order) elif self.order is not None and self.p.cancel: if self.datastatus > self.p.cancel: self.cancel(self.order) if self.datastatus: self.datastatus += 1 def start(self): if self.data0.contractdetails is not None: print('-- Contract Details:') print(self.data0.contractdetails) header = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume', 'OpenInterest', 'SMA'] print(', '.join(header)) self.done = False
def runstrategy():
args = parse_args()# Create a cerebro cerebro = bt.Cerebro() storekwargs = dict( token=args.token, account=args.account, practice=not args.live ) if not args.no_store: store = StoreCls(**storekwargs) if args.broker: if args.no_store: broker = BrokerCls(**storekwargs) else: broker = store.getbroker() cerebro.setbroker(broker) timeframe = bt.TimeFrame.TFrame(args.timeframe) # Manage data1 parameters tf1 = args.timeframe1 tf1 = bt.TimeFrame.TFrame(tf1) if tf1 is not None else timeframe cp1 = args.compression1 cp1 = cp1 if cp1 is not None else args.compression if args.resample or args.replay: datatf = datatf1 = bt.TimeFrame.Ticks datacomp = datacomp1 = 1 else: datatf = timeframe datacomp = args.compression datatf1 = tf1 datacomp1 = cp1 fromdate = None if args.fromdate: dtformat = '%Y-%m-%d' + ('T%H:%M:%S' * ('T' in args.fromdate)) fromdate = datetime.datetime.strptime(args.fromdate, dtformat) DataFactory = DataCls if args.no_store else store.getdata datakwargs = dict( timeframe=datatf, compression=datacomp, qcheck=args.qcheck, historical=args.historical, fromdate=fromdate, bidask=args.bidask, useask=args.useask, backfill_start=not args.no_backfill_start, backfill=not args.no_backfill, tz=args.timezone ) if args.no_store and not args.broker: # neither store nor broker datakwargs.update(storekwargs) # pass the store args over the data data0 = DataFactory(dataname=args.data0, **datakwargs) data1 = None if args.data1 is not None: if args.data1 != args.data0: datakwargs['timeframe'] = datatf1 datakwargs['compression'] = datacomp1 data1 = DataFactory(dataname=args.data1, **datakwargs) else: data1 = data0 rekwargs = dict( timeframe=timeframe, compression=args.compression, bar2edge=not args.no_bar2edge, adjbartime=not args.no_adjbartime, rightedge=not args.no_rightedge, takelate=not args.no_takelate, ) if args.replay: cerebro.replaydata(data0, **rekwargs) if data1 is not None: rekwargs['timeframe'] = tf1 rekwargs['compression'] = cp1 cerebro.replaydata(data1, **rekwargs) elif args.resample: cerebro.resampledata(data0, **rekwargs) if data1 is not None: rekwargs['timeframe'] = tf1 rekwargs['compression'] = cp1 cerebro.resampledata(data1, **rekwargs) else: cerebro.adddata(data0) if data1 is not None: cerebro.adddata(data1) if args.valid is None: valid = None else: valid = datetime.timedelta(seconds=args.valid) # Add the strategy cerebro.addstrategy(TestStrategy, smaperiod=args.smaperiod, trade=args.trade, exectype=bt.Order.ExecType(args.exectype), stake=args.stake, stopafter=args.stopafter, valid=valid, cancel=args.cancel, donotcounter=args.donotcounter, sell=args.sell, usebracket=args.usebracket) # Live data ... avoid long data accumulation by switching to "exactbars" cerebro.run(exactbars=args.exactbars) if args.exactbars < 1: # plotting is possible if args.plot: pkwargs = dict(style='line') if args.plot is not True: # evals to True but is not True npkwargs = eval('dict(' + args.plot + ')') # args were passed pkwargs.update(npkwargs) cerebro.plot(**pkwargs)
def parse_args(pargs=None):
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description='Test Oanda integration')parser.add_argument('--exactbars', default=1, type=int, required=False, action='store', help='exactbars level, use 0/-1/-2 to enable plotting') parser.add_argument('--stopafter', default=0, type=int, required=False, action='store', help='Stop after x lines of LIVE data') parser.add_argument('--no-store', required=False, action='store_true', help='Do not use the store pattern') parser.add_argument('--debug', required=False, action='store_true', help='Display all info received from source') parser.add_argument('--token', default=None, required=True, action='store', help='Access token to use') parser.add_argument('--account', default=None, required=True, action='store', help='Account identifier to use') parser.add_argument('--live', default=None, required=False, action='store', help='Go to live server rather than practice') parser.add_argument('--qcheck', default=0.5, type=float, required=False, action='store', help=('Timeout for periodic ' 'notification/resampling/replaying check')) parser.add_argument('--data0', default=None, required=True, action='store', help='data 0 into the system') parser.add_argument('--data1', default=None, required=False, action='store', help='data 1 into the system') parser.add_argument('--timezone', default=None, required=False, action='store', help='timezone to get time output into (pytz names)') parser.add_argument('--bidask', default=None, required=False, action='store_true', help='Use bidask ... if False use midpoint') parser.add_argument('--useask', default=None, required=False, action='store_true', help='Use the "ask" of bidask prices/streaming') parser.add_argument('--no-backfill_start', required=False, action='store_true', help='Disable backfilling at the start') parser.add_argument('--no-backfill', required=False, action='store_true', help='Disable backfilling after a disconnection') parser.add_argument('--historical', required=False, action='store_true', help='do only historical download') parser.add_argument('--fromdate', required=False, action='store', help=('Starting date for historical download ' 'with format: YYYY-MM-DD[THH:MM:SS]')) parser.add_argument('--smaperiod', default=5, type=int, required=False, action='store', help='Period to apply to the Simple Moving Average') pgroup = parser.add_mutually_exclusive_group(required=False) pgroup.add_argument('--replay', required=False, action='store_true', help='replay to chosen timeframe') pgroup.add_argument('--resample', required=False, action='store_true', help='resample to chosen timeframe') parser.add_argument('--timeframe', default=bt.TimeFrame.Names[1], choices=bt.TimeFrame.Names, required=False, action='store', help='TimeFrame for Resample/Replay') parser.add_argument('--compression', default=1, type=int, required=False, action='store', help='Compression for Resample/Replay') parser.add_argument('--timeframe1', default=None, choices=bt.TimeFrame.Names, required=False, action='store', help='TimeFrame for Resample/Replay - Data1') parser.add_argument('--compression1', default=None, type=int, required=False, action='store', help='Compression for Resample/Replay - Data1') parser.add_argument('--no-takelate', required=False, action='store_true', help=('resample/replay, do not accept late samples')) parser.add_argument('--no-bar2edge', required=False, action='store_true', help='no bar2edge for resample/replay') parser.add_argument('--no-adjbartime', required=False, action='store_true', help='no adjbartime for resample/replay') parser.add_argument('--no-rightedge', required=False, action='store_true', help='no rightedge for resample/replay') parser.add_argument('--broker', required=False, action='store_true', help='Use Oanda as broker') parser.add_argument('--trade', required=False, action='store_true', help='Do Sample Buy/Sell operations') parser.add_argument('--sell', required=False, action='store_true', help='Start by selling') parser.add_argument('--usebracket', required=False, action='store_true', help='Test buy_bracket') parser.add_argument('--donotcounter', required=False, action='store_true', help='Do not counter the 1st operation') parser.add_argument('--exectype', default=bt.Order.ExecTypes[0], choices=bt.Order.ExecTypes, required=False, action='store', help='Execution to Use when opening position') parser.add_argument('--stake', default=10, type=int, required=False, action='store', help='Stake to use in buy operations') parser.add_argument('--valid', default=None, type=float, required=False, action='store', help='Seconds to keep the order alive (0 means DAY)') parser.add_argument('--cancel', default=0, type=int, required=False, action='store', help=('Cancel a buy order after n bars in operation,' ' to be combined with orders like Limit')) # Plot options parser.add_argument('--plot', '-p', nargs='?', required=False, metavar='kwargs', const=True, help=('Plot the read data applying any kwargs passed\n' '\n' 'For example (escape the quotes if needed):\n' '\n' ' --plot style="candle" (to plot candles)\n')) if pargs is not None: return parser.parse_args(pargs) return parser.parse_args()
if name == 'main':
runstrategy() -
@cortex hello,
I'm learn to use backtrader ,and I'm trying to use the Oandatest.py with some problem. errormsg is the same with you.
I want to know how to run oandatest.py succeed, I have oanda account and token. and pip install oandapy.
but I can't run it succeed. please give me a hand. thanks very much.