def __init__(self, ticker: str, log: bool = True, no_console: bool = True): super().__init__(ticker) self.ticker = ticker if not (accountID and access_token): raise Exception("oandakey should hasn't been settled!") self.oanda = OandaAPI(accountID, access_token) if log: LoggerFactory('oandapyV20', info_log=False) if no_console: logging.getLogger('oandapyV20').propagate = False
class OandaReader(ReaderBase): host = 'localhost' port = 27017 def __init__(self, ticker: str, log: bool = True, no_console: bool = True): super().__init__(ticker) self.ticker = ticker if not (accountID and access_token): raise Exception("oandakey should hasn't been settled!") self.oanda = OandaAPI(accountID, access_token) if log: LoggerFactory('oandapyV20', info_log=False) if no_console: logging.getLogger('oandapyV20').propagate = False def load(self, fromdate=None, todate=None, frequency=None, count=2): return self.get_candles(count) def get_candles(self, count: int, frequency: str = None) -> list: if not frequency: frequency = self.env.sys_frequency data = self.oanda.get_candlestick_list(ticker=self.ticker, granularity=frequency, count=count) return self._format_candle(data) def load_by_cleaner(self, fromdate: str, todate: str, frequency: str) -> Generator: return (i for i in self.get_candles(5000, frequency)) @staticmethod def _format_candle(candle_data: list): ohlc_list = [] for candle in candle_data['candles']: ohlc = candle['mid'] ohlc['open'] = float(ohlc.pop("o")) ohlc['high'] = float(ohlc.pop("h")) ohlc['low'] = float(ohlc.pop("l")) ohlc['close'] = float(ohlc.pop("c")) ohlc['date'] = arrow.get( candle['time']).format("YYYY-MM-DD HH:mm:ss") ohlc['volume'] = float(candle['volume']) ohlc['complete'] = candle['complete'] ohlc_list.append(ohlc) return ohlc_list @property def bar_class(self): raise OandaBar
class Oanda_to_mongodb(MongodbConfig): def __init__(self, accountID, access_token, database, collection, host=None, port=None, print_log=True): super().__init__(database, collection, host, port) self.api = OandaAPI(accountID, access_token) self.print_log = print_log def _normalize(self, candle): date = candle['time'].replace('T', ' ')[:19] ohlc = dict(date=date, timestamp=date[-8:], open=float(candle['mid']['o']), high=float(candle['mid']['h']), low=float(candle['mid']['l']), close=float(candle['mid']['c']), volume=float(candle['volume']), complete=float(candle['complete'])) return ohlc def _combine_and_insert(self, data): data = data['candles'] candle_list = fy.walk(self._normalize, data) lenth = len(candle_list) coll = self._set_collection() i = 0 for bar in candle_list: i += 1 coll.insert_one(bar) if self.print_log: date = bar['date'] # print(f'Inserting {i}, Total: {lenth}, date: {date}') def candle_to_db(self, instrument, granularity, count=50, fromdate=None, todate=None, price='M', smooth=False, includeFirst=None): """ granularity: S5, S10, S30, M1, M2, M4, M5, M10, M15, M30 H1, H2, H3, H4, H6, H8, H12, D, W, M """ data = self.api.get_candlestick_list(instrument, granularity, count, fromdate, todate, price, smooth, includeFirst) self._combine_and_insert(data)
def __init__(self, accountID, access_token, database, collection, host=None, port=None, print_log=True): super().__init__(database, collection, host, port) self.api = OandaAPI(accountID, access_token) self.print_log = print_log
def __init__(self): super().__init__() self.oanda = OandaAPI(accountID, access_token)
class OandaBroker(ForexBroker): def __init__(self): super().__init__() self.oanda = OandaAPI(accountID, access_token) def _submit_order(self): for mkt_order in self.env.orders_mkt_submitted_cur: self.send_mkt_order_with_pending(mkt_order) for pending in self.env.orders_pending: self.send_pending_order_with_pending(pending) self.clear_pending() def get_order_info(self, pending_list): order_info = {} for order in pending_list: if 'takeprofit' in order.trigger_key: order_info['takeprofit'] = order.target_price elif 'stoploss' in order.trigger_key: order_info['stoploss'] = order.target_price elif 'trailingstop' in order.trigger_key: cur_price = self.env.feeds[order.ticker].cur_price order_info['trailingstop'] = order.difference return order_info def is_mkt_only(self, order): if order.mkt_id in self.env.orders_child_of_mkt_dict: return False return True def send_to_broker(self, mkt, order_info=None): if order_info: self.oanda.OrderCreate_mkt(**order_info) return self.oanda.OrderCreate_mkt(mkt.ticker, mkt.size * self.direction(mkt)) def send_mkt_order_with_pending(self, mkt_order): if self.is_mkt_only(mkt_order): self.send_to_broker(mkt_order) else: pending_list = self.env.orders_child_of_mkt_dict[mkt_order.mkt_id] order_info = self.get_order_info(pending_list) order_info['ticker'] = mkt_order.ticker order_info['size'] = mkt_order.size * self.direction(mkt_order) self.send_to_broker(mkt_order, order_info) def send_pending_order_with_pending(self, order): params = self.target_price_for_live(order) params.update( dict(ticker=order.ticker, size=order.size * self.direction(order), price=order.target_price)) if order.order_type == OrderType.Limit: params.update(dict(requesttype='LimitOrder')) elif order.order_type == OrderType.Stop: params.update(dict(requesttype='StopOrder')) self.oanda.OrderCreate_pending(**params) def direction(self, order): if order.action_type in [ActionType.Short, ActionType.Sell]: return -1 return 1 def clear_pending(self): self.env.orders_pending = [] self.env.orders_child_of_mkt_dict = {} def run(self): self._clear_submited_order() self._generate_order() self._check_order() self._submit_order() def target_price_for_live(self, order): def below_price(diff): return order.signal.price - diff def above_price(diff): return order.signal.price + diff def target_price(): return order.signal.price params = {} division = dollar_per_pips(order.ticker, order.first_cur_price) if order.signal.action_type == ActionType.Buy: if order.signal.get('stoploss'): money = order.signal.get('stoploss') diff = money / order.signal.size / division result = below_price(diff) params.update(dict(stoploss=result)) if order.signal.get('takeprofit'): money = order.signal.get('takeprofit') diff = money / order.signal.size / division result = above_price(diff) params.update(dict(takeprofit=result)) if order.signal.get('trailingstop'): money = order.signal.get('trailingstop') diff = money / order.signal.size / division params.update(dict(trailingstop=diff)) if order.signal.get('stoploss_pct'): pct = order.signal.get('stoploss_pct') diff = pct * target_price() / division result = below_price(diff) params.update(dict(stoploss=result)) if order.signal.get('takeprofit_pct'): pct = order.signal.get('takeprofit_pct') diff = pct * target_price() / division result = above_price(diff) params.update(dict(takeprofit=result)) if order.signal.get('trailingstop_pct'): pct = order.signal.get('trailingstop_pct') diff = pct * target_price() / division params.update(dict(trailingstop=diff)) elif order.signal.action_type == ActionType.Short: if order.signal.get('stoploss'): money = order.signal.get('stoploss') diff = money / order.signal.size / division result = above_price(diff) params.update(dict(stoploss=result)) if order.signal.get('takeprofit'): money = order.signal.get('takeprofit') diff = money / order.signal.size / division result = below_price(diff) params.update(dict(takeprofit=result)) if order.signal.get('trailingstop'): money = order.signal.get('trailingstop') diff = money / order.signal.size / division params.update(dict(trailingstop=diff)) if order.signal.get('stoploss_pct'): pct = order.signal.get('stoploss_pct') diff = pct * target_price() / division result = above_price(diff) params.update(dict(stoploss=result)) if order.signal.get('takeprofit_pct'): pct = order.signal.get('takeprofit_pct') diff = pct * target_price() / division result = below_price(diff) params.update(dict(takeprofit=result)) if order.signal.get('trailingstop_pct'): pct = order.signal.get('trailingstop_pct') diff = pct * target_price() / division params.update(dict(trailingstop=diff)) return params
class OandaRecorder(ForexRecorder): def __init__(self): super().__init__() self.oanda = OandaAPI(accountID, access_token) def initialize(self): self.settle_match_engine_and_series() self.holding_pnl = self.series.HoldingPnlSeries(250) self.realized_pnl = self.series.RealizedPnlSeries(250) self.commission = self.series.CommissionSeries(250) self.market_value = self.series.MarketValueSeries(250) self.margin = self.series.MarginSeries(250) # 无法更新,没有分别提供long,short信息 self.position = PositionSeries(250) self.avg_price = AvgPriceSeries(250) self.cash = MoneySeries("cash", self.initial_cash, 250) self.frozen_cash = MoneySeries("frozen_cash", 0, 250) self.balance = MoneySeries("balance", self.initial_cash, 250) account_details = self.oanda.get_AccountDetails() account = account_details["account"] positions = account["positions"] for position in positions: ticker = position["instrument"] if ticker in self.env.tickers: for long_or_short in ["long", "short"]: info = position[long_or_short] self.position.change_initial_value( ticker, abs(float(info["units"])), long_or_short) self.holding_pnl.change_initial_value( ticker, float(info["unrealizedPL"]), long_or_short) self.commission.change_initial_value( ticker, float(position["commission"]), long_or_short) if info.get("averagePrice"): self.avg_price.change_initial_value( ticker, float(info["averagePrice"]), long_or_short) else: self.avg_price.change_initial_value( ticker, 0, long_or_short) self.cash.change_initial_value(float(account["marginAvailable"])) self.balance.change_initial_value(float(account["NAV"])) self.frozen_cash.change_initial_value(float(account["marginUsed"])) def set_setting(self, slippage: dict, margin_rate=0.02) -> None: self.slippage = slippage self.margin_rate = margin_rate def run(self): # self._record_order() pass def update(self, order_executed=False): """取消了margin,market_value,""" trading_date = arrow.now().format("YYYY-MM-DD HH:mm:ss") account_details = self.oanda.get_AccountDetails() account = account_details["account"] positions = account["positions"] for position in positions: ticker = position["instrument"] if ticker in self.env.tickers: for long_or_short in ["long", "short"]: info = position[long_or_short] self.position._append_value(ticker, abs(float(info["units"])), long_or_short) self.holding_pnl._append_value(ticker, float(info["unrealizedPL"]), long_or_short) self.commission._append_value( ticker, float(position["commission"]), long_or_short) if info.get("averagePrice"): self.avg_price.change_initial_value( ticker, float(info["averagePrice"]), long_or_short) else: self.avg_price.change_initial_value( ticker, 0, long_or_short) self.cash.append({ "date": trading_date, "value": float(account["marginAvailable"]) }) self.balance.append({ "date": trading_date, "value": float(account["NAV"]) }) self.frozen_cash.append({ "date": trading_date, "value": float(account["marginUsed"]) }) self.market_value.update_barly(False) self.margin.update_barly() def none(self): if not order_executed: positions = self.oanda.get_AccountDetails( )["account"]["positions"][0] true_holing_pnl = (self.holding_pnl.total_value() - self.commission.total_value()) print("=" * 30) print("balance", self.balance.latest()) print("size", self.position.total_value(), positions["long"]["units"]) print("margin", self.margin.total_value(), positions["marginUsed"]) print("cash", self.cash.latest()) print( "holding_pnl", self.holding_pnl.total_value(), positions["long"]["unrealizedPL"], ) print("true holding_pnl", true_holing_pnl) print("commission", self.commission.total_value(), positions["commission"]) print("market_value", self.market_value.total_value()) try: print( "avgPrice", self.avg_price.latest("EUR_USD", "long"), positions["long"]["averagePrice"], ) except: print("no position") @property def bar_class(self): return OandaBar