def test_ibgw_restart(ib_docker):

    subprocess.check_output(
        ['docker', 'container', 'stop', ib_docker]).decode().strip()
    subprocess.check_output(
        ['docker', 'container', 'start', ib_docker]).decode().strip()
    
    ib = IB()
    wait = 60
    while not ib.isConnected():
        try:
            IB.sleep(1)
            ib.connect('localhost', 4002, clientId=999)
        except:
            pass
        wait -= 1
        if wait <= 0:
            break
    
    contract = Forex('EURUSD')
    bars = ib.reqHistoricalData(
        contract, endDateTime='', durationStr='30 D',
        barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)

    # convert to pandas dataframe:
    df = util.df(bars)
    print(df)
예제 #2
0
def test_ibgw_port(host):
    account = os.environ['IB_ACCOUNT']
    password = os.environ['IB_PASSWORD']
    trade_mode = os.environ['TRADE_MODE']
    # build local ./Dockerfile
    subprocess.check_call(['docker', 'build', '-t', IMAGE_NAME, '.'])

    # run a container
    docker_id = subprocess.check_output(
        ['docker', 'run', 
        '--env', 'IB_ACCOUNT={}'.format(account),
        '--env', 'IB_PASSWORD={}'.format(password),
        '--env', 'TRADE_MODE={}'.format(trade_mode),
        '-p', '4002:4002',
        '-d', IMAGE_NAME, 
        "tail", "-f", "/dev/null"]).decode().strip()
    
    time.sleep(60)
    ib = IB()
    ib.connect('localhost', 4002, clientId=1)
    contract = Forex('EURUSD')
    bars = ib.reqHistoricalData(
        contract, endDateTime='', durationStr='30 D',
        barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)

    # convert to pandas dataframe:
    df = util.df(bars)
    print(df)

    # at the end of the test suite, destroy the container
    subprocess.check_call(['docker', 'rm', '-f', docker_id])
예제 #3
0
 def get_contract(self):
     if self.market == 'futures':
         expiration = self.ib.reqContractDetails(Future(self.symbol,self.exchange))[0].contract.lastTradeDateOrContractMonth 
         self.contract = Future(symbol=self.symbol, exchange=self.exchange, lastTradeDateOrContractMonth=expiration)
     elif self.market == 'forex':
         self.contract = Forex(self.symbol)
     elif self.market == 'stocks':
         self.contract = Stock(symbol=self.symbol, exchange=self.exchange, currency='USD')
예제 #4
0
def main(ib):
    from ib_insync import Stock, Forex, Index
    win_historical_ticks = sg.Window('IBKR Historical Ticks', layout)
    #win_historical_ticks.Element('_TickCount_').Update('0')
    
    # Event Loop to process "events" and get the "values" of the inputs
    while True:  # Event Loop
        event, values = win_historical_ticks.Read()

        if event == '_CloseWindow_':
            #? commenting out "disconnect()" because any calling procedure would not want a child to disconnect it
            #ib.disconnect()
            logging.info("Close hit")
            win_historical_ticks.close()
            break

        if event == 'Qualify':
            # Update the "output" element to be the value of "input" element
            win_historical_ticks.Element('_OUTPUT_').Update(values['_Symbol_'])
            if values['_SecType_'] == 'STK':
                contract = Stock(values['_Symbol_'], values['_Exchange_'],values['_Currency_'])
            if values['_SecType_'] == 'CASH':
                contract = Forex(values['_Symbol_'])
            if values['_SecType_'] == 'IND':
                contract = Index(values['_Symbol_'], values['_Exchange_'],values['_Currency_'])
            qual = ib.qualifyContracts(contract)
            logging.info(str(qual))

        if event == 'Fetch':
            #NOTE add validations here
            if values['_targetFolder_'] != '':
                dtmStartTime = datetime.strptime(str(values['_StartDate_']), '%Y-%m-%d %H:%M:%S')
                dtmStartTime = dtmStartTime.replace(hour=0, minute=1)
                dtmEndTime  = datetime.strptime(str(values['_EndDate_']), '%Y-%m-%d %H:%M:%S')
                dtmEndTime = dtmEndTime.replace(hour=23, minute=59)
                
                intTicks = int(values['_tickCount_'])
                # whatToShow (str) – One of ‘Bid_Ask’, ‘Midpoint’ or ‘Trades’.
                strWhatToShow = str(values['_whatToShow_'])
                # useRTH – If True then only show data from within Regular Trading Hours, if False then show all data.
                boolUseRTH = bool(values['_useRTH_'])
                # ignoreSize (bool) – Ignore bid/ask ticks that only update the size.
                boolIgnoreSize = bool(values['_ignoreSize_'])
                #sg.popup(str([dtmStartTime, " - ", dtmEndTime, " - ", intTicks, " - ", strWhatToShow, " - ", boolUseRTH, " - ", boolIgnoreSize]))
                if dtmEndTime > dtmStartTime:
                    listTicks = loop_reqHistoricalTicks(ib, contract, dtmStartTime, dtmEndTime, intTicks, strWhatToShow, boolUseRTH, boolIgnoreSize)
                #convert listTicks to a CSV and save
                dfTicks = pd.DataFrame(listTicks)
                dfTicks = dfTicks.rename(columns={'tickAttribLast':'symbol', 'specialConditions':'currency'})
                dfTicks['symbol'] = contract.symbol
                dfTicks['exchange'] = contract.exchange
                dfTicks['currency'] = contract.currency
                dfTicks['time'] = dfTicks['time'].apply(utc2local)
                dfTicks['dataType'] = 'Ticks_' + str(values['_whatToShow_']) +('_RTH' if boolUseRTH else '_RHT+AMO')
                #For Linux uncomment below
                #dfTicks.to_csv(values['_targetFolder_'] +'/'+ contract.symbol +'_'+ str(dtmStartTime) +'_'+ str(dtmEndTime)+'.csv', index=False)
                #For Windows uncomment below
                dfTicks.to_csv(str_default_path +'//'+ contract.symbol +'_'+ dtmStartTime.strftime("%Y%M%d_%H%M%S") +'_'+ dtmEndTime.strftime("%Y%M%d_%H%M%S") +'.csv', index=False)
예제 #5
0
 def get_contract(self):
     if self.market == 'futures':
         local = self._local_symbol_selection()
         self.contract = Future(symbol=self.symbol,
                                exchange=self.exchange,
                                localSymbol=local)
         print(
             self.ib.reqContractDetails(
                 self.contract)[0].contract.lastTradeDateOrContractMonth)
         '''expiration = self.ib.reqContractDetails(Future(self.symbol,self.exchange))[0].contract.lastTradeDateOrContractMonth
         self.contract = Future(symbol=self.symbol, exchange=self.exchange, lastTradeDateOrContractMonth=expiration)'''
     elif self.market == 'forex':
         self.contract = Forex(self.symbol)
     elif self.market == 'stocks':
         self.contract = Stock(symbol=self.symbol,
                               exchange=self.exchange,
                               currency='USD')
예제 #6
0
def fnCreateIBSymbol(ticker_tk=None, ticker_at=None):

    if not ticker_tk:
        ticker_tk = 'SPY'
    if not ticker_at:
        ticker_at = 'EQT'

    symIB = None

    if ticker_at == 'EQT':
        symIB = [ticker_tk, Stock(ticker_tk, 'SMART', 'USD')]
    elif ticker_at == 'FUT':
        symIB = [ticker_tk, Future(ticker_tk, 'SMART', 'USD')]
    elif ticker_at == 'FX':
        symIB = [ticker_tk, Forex(ticker_tk, 'IDEALPRO')]

    return symIB
async def generate_market_depth(n_records=50):
    ib = get_cached_ib_client(os.environ["TWS_USERNAME"],
                              os.environ["TWS_PASSWORD"])
    [contract] = ib.qualifyContracts(Forex("EURUSD"))
    ticker = ib.reqMktDepth(contract=contract)

    data = []

    def record(x):
        data.append(copy.copy(x))

    ticker.updateEvent += record

    while len(data) < n_records:
        await asyncio.sleep(0.1)

    with open(STREAMING_PATH / "eurusd_depth.pkl", "wb") as f:
        f.write(pickle.dumps(data))
예제 #8
0
    def _get_currencies(self, base_currency):
        """
        Gets the FX rates for all involved contracts.

        :param base_currency: base currency of IB account in ISO format (str)
        """

        currencies = [c.contract.currency for c in self._contracts.values()]
        tickers = [
            self._ib_gw.reqTickers(Forex(c + base_currency))[0]
            for c in currencies
        ]
        fx_rates = [
            t.midpoint() if t.midpoint() == t.midpoint() else t.close
            for t in tickers
        ]
        self._fx = {
            currency: 1 if currency == base_currency else fx_rate
            for currency, fx_rate in zip(currencies, fx_rates)
        }
def test_ibgw_interactive(ib_docker):
    ib = IB()
    wait = 120
    while not ib.isConnected():
        try:
            IB.sleep(1)
            ib.connect('localhost', 4002, clientId=999)
        except:
            pass
        wait -= 1
        if wait <= 0:
            break
    
    contract = Forex('EURUSD')
    bars = ib.reqHistoricalData(
        contract, endDateTime='', durationStr='30 D',
        barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)

    # convert to pandas dataframe:
    df = util.df(bars)
    print(df)
예제 #10
0
    def pull_from_IB(self, start, end, market='EURUSD', freq='1 hour'):
        '''
        Note, all times should be UTC (aka Zulu, Z, GMT)

        :param start: string in datetime format, eg. '2019-07-18 17:15:00'
        :param end: same format as start
        :param freq: Must be one of: ‘1 secs’, ‘5 secs’, ‘10 secs’ 15 secs’, 
                ‘30 secs’, ‘1 min’, ‘2 mins’, ‘3 mins’, ‘5 mins’, ‘10 mins’,
                ‘15 mins’, ‘20 mins’, ‘30 mins’, ‘1 hour’, ‘2 hours’, 
                ‘3 hours’, ‘4 hours’, ‘8 hours’, ‘1 day’, ‘1 week’,
                ‘1 month’ (see IB Docs)
        '''
        #Parse the requested window so API calls are not as lengthy
        time_list = self.parse_datetime(start, end, freq)
        df_list = []
        contract = Forex(market)
        for time_pair in time_list:
            '''
            useRTH (bool) – If True then only show data from within Regular Trading Hours,
                    if False then show all data.
            formatDate (int) – For an intraday request setting to 2 will cause the returned
                    date fields to be timezone-aware datetime.datetime with UTC timezone,
                    instead of local timezone as used by TWS.
            '''
            bars = self.ib.reqHistoricalData(contract,
                                             endDateTime=time_pair[0],
                                             durationStr=time_pair[1],
                                             barSizeSetting=freq,
                                             whatToShow='MIDPOINT',
                                             useRTH=True)

            # convert to pandas dataframe:
            df = util.df(bars)
            #drop columns ['barCount', 'average']
            df_list.append(df[['date', 'open', 'high', 'low', 'close']].copy())
        return df_list
예제 #11
0
from ib_insync import IB, util, Forex

if __name__ == "__main__":
    ib = IB()
    ib.connect('localhost', 4001, clientId=1)
    contract = Forex('EURUSD')
    bars = ib.reqHistoricalData(contract,
                                endDateTime='',
                                durationStr='30 D',
                                barSizeSetting='1 hour',
                                whatToShow='MIDPOINT',
                                useRTH=True)

    # convert to pandas dataframe:
    df = util.df(bars)
    print(df)
예제 #12
0
def main():
    # query config
    config = db.collection('config').document('paper' if TRADING_MODE == 'local' else TRADING_MODE).get().to_dict()

    # activity log for Firestore
    activity_log = {
        'agent': (re.match('([\\w-]+)-([0-9]+|manual-[0-9a-z]+)-[0-9a-z]+$', HOSTNAME)).group(1) if HOSTNAME is not None else 'localhost',
        'environment': {'DRY_RUN': DRY_RUN, 'ORDER_PROPERTIES': ORDER_PROPERTIES, 'STRATEGIES': STRATEGIES, 'TRADING_MODE': TRADING_MODE},
        'config': config,
        'exception': None
    }

    main_e = None
    try:
        strategies = STRATEGIES.split(',') if STRATEGIES is not None else []
        gateway = 'localhost' if TRADING_MODE == 'local' else 'ib-gw-' + TRADING_MODE
        order_properties = json.loads(ORDER_PROPERTIES)

        logger.info('Running allocator for {}...'.format(strategies))

        # get signals for all strategies
        signals = {s: get_signal('localhost' if TRADING_MODE == 'local' else s) for s in strategies}
        activity_log['signals'] = signals
        # scale w/ exposure
        scaled_signals = [
            {
                instr: alloc * config['exposure']['strategies'][strat]
                for instr, alloc in sig.items()
            } for strat, sig in signals.items()
        ]
        activity_log['scaledSignals'] = scaled_signals

        # consolidate strategies
        allocation = make_allocation(scaled_signals)
        activity_log['allocation'] = allocation
        logger.info('Allocation: {}'.format(activity_log['allocation']))

        # connect to IB gateway
        ib_gw.connect(gateway, 4003, 1)

        # get net liquidation value
        account_values = get_account_values(config['account'])
        base_currency = list(account_values['NetLiquidation'].keys())[0]
        net_liquidation = float(account_values['NetLiquidation'][base_currency])
        activity_log['netLiquidation'] = net_liquidation

        # get positions
        positions = {item.contract.conId: item.position for item in ib_gw.positions(config['account'])}
        activity_log['positions'] = positions

        # get contract details
        contract_data = get_contract_data(set(list(allocation.keys()) + list(positions.keys())))
        # build contractId->symbol lookup dict
        symbol_map = {k: v['contract'].localSymbol for k, v in contract_data.items()}
        activity_log['contractIds'] = {v['contract'].localSymbol: k for k, v in contract_data.items()}
        # replace dict keys
        activity_log['signals'] = {k: {symbol_map[k]: v for k, v in v.items()} for k, v in signals.items()}
        activity_log['scaledSignals'] = [{symbol_map[k]: v for k, v in s.items()} for s in scaled_signals]
        activity_log['allocation'] = {symbol_map[k]: v for k, v in allocation.items()}
        activity_log['positions'] = {symbol_map[k]: v for k, v in positions.items()}

        # get relevant currencies and corresponding FX ratese
        currencies = {v['contract'].currency for v in contract_data.values()}
        fx = {
            c: 1 if c == base_currency else get_tickers(Forex(c + base_currency))
            for c in currencies
        }
        activity_log['fx'] = {
            v.contract.symbol + v.contract.currency: v.midpoint()
            if v.midpoint() == v.midpoint() else v.close
            for v in fx.values()
        }

        # calculate target positions
        target_positions = {
            k: round(config['exposure']['overall'] * v * net_liquidation
                     / (contract_data[k]['ticker'].close
                        * int(contract_data[k]['contract'].multiplier)
                        * (fx[contract_data[k]['contract'].currency].midpoint()
                           if fx[contract_data[k]['contract'].currency].midpoint() == fx[contract_data[k]['contract'].currency].midpoint()
                           else fx[contract_data[k]['contract'].currency].close)))
            for k, v in allocation.items()
        }

        for k in target_positions.keys():
            if k not in positions:
                positions[k] = 0
        for k in positions.keys():
            if k not in target_positions:
                target_positions[k] = 0
        activity_log['positions'] = {symbol_map[k]: v for k, v in positions.items()}
        activity_log['targetPositions'] = {symbol_map[k]: v for k, v in target_positions.items()}

        # calculate trade
        trades = {k: target_positions[k] - positions[k] for k in target_positions.keys()}
        trades = {k: int(v) for k, v in trades.items() if v != 0}
        activity_log['trades'] = {symbol_map[k]: v for k, v in trades.items()}
        logger.info('Trades: {}'.format(activity_log['trades']))

        perm_ids = []
        if not DRY_RUN:
            # place orders
            for k, v in trades.items():
                order = ib_gw.placeOrder(contract_data[k]['contract'],
                                         MarketOrder(action='BUY' if v > 0 else 'SELL',
                                                     totalQuantity=abs(v)).update(**order_properties))
                perm_ids.append(order.order.permId)
        ib_gw.sleep(5)  # give the IB Gateway a couple of seconds to digest orders and to raise possible errors
        activity_log['orders'] = {
            t.contract.localSymbol: {
                'order': {
                    k: v
                    for k, v in t.order.nonDefaults().items()
                    if isinstance(v, (int, float, str))
                },
                'orderStatus': {
                    k: v
                    for k, v in t.orderStatus.nonDefaults().items()
                    if isinstance(v, (int, float, str))
                },
                'isActive': t.isActive()
            } for t in ib_gw.trades() if t.order.permId in perm_ids
        }
        logging.info('Orders placed: {}'.format(activity_log['orders']))

    except Exception as e:
        logger.error(e)
        activity_log['exception'] = str(e)
        main_e = e

    finally:
        ib_gw.disconnect()

        try:
            activity_log['timestamp'] = datetime.now(timezone.utc)
            db.collection('activity').document().set(activity_log)
        except Exception as e:
            logger.error(e)
            logger.info(activity_log)

    if main_e is not None:
        # raise main exception so that CronJob is restarted
        raise main_e

    logger.info('Done.')
예제 #13
0
    def ib_spotfx_contract(self, ccy1, ccy2="USD", log=arg_not_supplied):
        ibcontract = Forex(ccy1 + ccy2)

        ibcontract = self.ib_resolve_unique_contract(ibcontract)

        return ibcontract
예제 #14
0
import os

from ib_insync import Forex

from models.hft_model_1 import HftModel1

if __name__ == '__main__':
    TWS_HOST = os.environ.get('TWS_HOST', '127.0.0.1')
    TWS_PORT = os.environ.get('TWS_PORT', 7497)

    print('Connecting on host:', TWS_HOST, 'port:', TWS_PORT)

    model = HftModel1(
        host=TWS_HOST,
        port=TWS_PORT,
        client_id=2,
    )

    to_trade = [('EURUSD', Forex('EURUSD')), ('USDJPY', Forex('USDJPY'))]

    model.run(to_trade=to_trade, trade_qty=100)
예제 #15
0
    def ib_spotfx_contract(self, ccy1, ccy2="USD") -> Forex:

        ibcontract = Forex(ccy1 + ccy2)
        ibcontract = self.ib_resolve_unique_contract(ibcontract)

        return ibcontract
예제 #16
0
def fnRunIBTrader():

    setPandas()
    setLogging(LOGGING_DIRECTORY=os.path.join('../logging/',
                                              dt.today().strftime('%Y-%m-%d')),
               LOG_FILE_NAME=os.path.basename(__file__),
               level=LOG_LEVEL)

    logging.info('Running script {}'.format(os.path.basename(__file__)))
    logging.info('Process ID: {}'.format(os.getpid()))
    curDate = dt.today().strftime('%Y-%m-%d')

    try:
        TWS_HOST = os.environ.get('TWS_HOST', 'tws')
        TWS_PORT = os.environ.get('TWS_PORT', 4003)
        logging.info('Connecting on host: {} port: {}'.format(
            TWS_HOST, TWS_PORT))

        tickerIB = fnCreateIBSymbol(ticker_tk='SPY', ticker_at='EQT')
        ib = IB()

        # connect
        connTrading = fnOdbcConnect(user='******',
                                    password='******',
                                    host='127.0.0.1',
                                    port='3306',
                                    dbName='trading')

        while True:
            if not ib.isConnected():
                try:
                    id = randint(0, 9999)
                    ib.connect('tws', 4003, clientId=id, timeout=60)
                    ib.waitonupdate(timeout=0.1)
                    ib.sleep(3)
                    break
                except Exception as e:
                    print(e)
                    ib.waitonupdate(timeout=0.1)
                    ib.sleep(3)
                    continue

            else:
                contract = Forex('EURUSD')
                bars = ib.reqHistoricalData(contract,
                                            endDateTime='',
                                            durationStr='600 S',
                                            barSizeSetting='1 min',
                                            whatToShow='MIDPOINT',
                                            useRTH=False,
                                            keepUpToDate=False)
                bars = util.df(bars)

                bars['date'] = pd.to_datetime(bars['date']).dt.tz_localize(
                    'UTC').dt.strftime('%Y-%m-%d %H:%M:%S')
                bars = bars[[
                    'date', 'open', 'high', 'low', 'close', 'volume', 'average'
                ]]
                fnUploadSQL(bars,
                            connTrading,
                            'forex_data_EURUSD',
                            'REPLACE',
                            None,
                            unlinkFile=True)

        logging.info('----- END PROGRAM -----')

    except Exception as e:
        logging.error(str(e), exc_info=True)

    # CLOSE LOGGING
    for handler in logging.root.handlers:
        handler.close()
    logging.shutdown()
예제 #17
0
class TestIBInstrumentProvider:
    def setup(self):
        self.ib = MagicMock()
        self.loop = asyncio.get_event_loop()
        self.clock = LiveClock()
        self.logger = LiveLogger(
            loop=self.loop,
            clock=self.clock,
            level_stdout=LogLevel.DEBUG,
        )
        self.provider = InteractiveBrokersInstrumentProvider(
            client=self.ib,
            logger=self.logger,
            config=InstrumentProviderConfig())

    @staticmethod
    def async_return_value(value: object) -> asyncio.Future:
        future: asyncio.Future = asyncio.Future()
        future.set_result(value)
        return future

    @pytest.mark.parametrize(
        "filters, expected",
        [
            (
                {
                    "secType": "STK",
                    "symbol": "AMD",
                    "exchange": "SMART",
                    "currency": "USD"
                },
                Stock("AMD", "SMART", "USD"),
            ),
            (
                {
                    "secType": "STK",
                    "symbol": "INTC",
                    "exchange": "SMART",
                    "primaryExchange": "NASDAQ",
                    "currency": "USD",
                },
                Stock("INTC", "SMART", "USD", primaryExchange="NASDAQ"),
            ),
            (
                {
                    "secType": "CASH",
                    "symbol": "EUR",
                    "currency": "USD",
                    "exchange": "IDEALPRO"
                },
                Forex(symbol="EUR", currency="USD"),
            ),  # EUR/USD,
            ({
                "secType": "CFD",
                "symbol": "IBUS30"
            }, CFD("IBUS30")),
            (
                {
                    "secType": "FUT",
                    "symbol": "ES",
                    "exchange": "GLOBEX",
                    "lastTradeDateOrContractMonth": "20180921",
                },
                Future("ES", "20180921", "GLOBEX"),
            ),
            (
                {
                    "secType": "OPT",
                    "symbol": "SPY",
                    "exchange": "SMART",
                    "lastTradeDateOrContractMonth": "20170721",
                    "strike": 240,
                    "right": "C",
                },
                Option("SPY", "20170721", 240, "C", "SMART"),
            ),
            (
                {
                    "secType": "BOND",
                    "secIdType": "ISIN",
                    "secId": "US03076KAA60"
                },
                Bond(secIdType="ISIN", secId="US03076KAA60"),
            ),
            (
                {
                    "secType": "CRYPTO",
                    "symbol": "BTC",
                    "exchange": "PAXOS",
                    "currency": "USD"
                },
                Crypto("BTC", "PAXOS", "USD"),
            ),
        ],
    )
    def test_parse_contract(self, filters, expected):
        result = self.provider._parse_contract(**filters)
        fields = [
            f.name for f in expected.__dataclass_fields__.values()
            if getattr(expected, f.name)
        ]
        for f in fields:
            assert getattr(result, f) == getattr(expected, f)

    @pytest.mark.asyncio
    async def test_load_equity_contract_instrument(self, mocker):
        # Arrange
        instrument_id = InstrumentId.from_str("AAPL.NASDAQ")
        contract = IBTestStubs.contract(symbol="AAPL")
        contract_details = IBTestStubs.contract_details("AAPL")
        mocker.patch.object(
            self.provider._client,
            "reqContractDetailsAsync",
            return_value=self.async_return_value([contract_details]),
        )
        mocker.patch.object(
            self.provider._client,
            "qualifyContractsAsync",
            return_value=self.async_return_value([contract]),
        )

        # Act
        await self.provider.load(secType="STK",
                                 symbol="AAPL",
                                 exchange="NASDAQ")
        equity = self.provider.find(instrument_id)

        # Assert
        assert InstrumentId(symbol=Symbol("AAPL"),
                            venue=Venue("NASDAQ")) == equity.id
        assert equity.asset_class == AssetClass.EQUITY
        assert equity.asset_type == AssetType.SPOT
        assert 100 == equity.multiplier
        assert Price.from_str("0.01") == equity.price_increment
        assert 2, equity.price_precision

    @pytest.mark.asyncio
    async def test_load_futures_contract_instrument(self, mocker):
        # Arrange
        instrument_id = InstrumentId.from_str("CLZ2.NYMEX")
        contract = IBTestStubs.contract(symbol="CLZ2", exchange="NYMEX")
        contract_details = IBTestStubs.contract_details("CLZ2")
        mocker.patch.object(
            self.provider._client,
            "reqContractDetailsAsync",
            return_value=self.async_return_value([contract_details]),
        )
        mocker.patch.object(
            self.provider._client,
            "qualifyContractsAsync",
            return_value=self.async_return_value([contract]),
        )

        # Act
        await self.provider.load(symbol="CLZ2", exchange="NYMEX")
        future = self.provider.find(instrument_id)

        # Assert
        assert future.id == instrument_id
        assert future.asset_class == AssetClass.INDEX
        assert future.multiplier == 1000
        assert future.price_increment == Price.from_str("0.01")
        assert future.price_precision == 2

    @pytest.mark.asyncio
    async def test_load_options_contract_instrument(self, mocker):
        # Arrange
        instrument_id = InstrumentId.from_str("AAPL211217C00160000.SMART")
        contract = IBTestStubs.contract(secType="OPT",
                                        symbol="AAPL211217C00160000",
                                        exchange="NASDAQ")
        contract_details = IBTestStubs.contract_details("AAPL211217C00160000")
        mocker.patch.object(
            self.provider._client,
            "reqContractDetailsAsync",
            return_value=self.async_return_value([contract_details]),
        )
        mocker.patch.object(
            self.provider._client,
            "qualifyContractsAsync",
            return_value=self.async_return_value([contract]),
        )

        # Act
        await self.provider.load(secType="OPT",
                                 symbol="AAPL211217C00160000",
                                 exchange="SMART")
        option = self.provider.find(instrument_id)

        # Assert
        assert option.id == instrument_id
        assert option.asset_class == AssetClass.EQUITY
        assert option.multiplier == 100
        assert option.expiry_date == datetime.date(2021, 12, 17)
        assert option.strike_price == Price.from_str("160.0")
        assert option.kind == OptionKind.CALL
        assert option.price_increment == Price.from_str("0.01")
        assert option.price_precision == 2

    @pytest.mark.asyncio
    async def test_load_forex_contract_instrument(self, mocker):
        # Arrange
        instrument_id = InstrumentId.from_str("EUR/USD.IDEALPRO")
        contract = IBTestStubs.contract(secType="CASH",
                                        symbol="EURUSD",
                                        exchange="IDEALPRO")
        contract_details = IBTestStubs.contract_details("EURUSD")
        mocker.patch.object(
            self.provider._client,
            "reqContractDetailsAsync",
            return_value=self.async_return_value([contract_details]),
        )
        mocker.patch.object(
            self.provider._client,
            "qualifyContractsAsync",
            return_value=self.async_return_value([contract]),
        )

        # Act
        await self.provider.load(secType="CASH",
                                 symbol="EURUSD",
                                 exchange="IDEALPRO")
        fx = self.provider.find(instrument_id)

        # Assert
        assert fx.id == instrument_id
        assert fx.asset_class == AssetClass.FX
        assert fx.multiplier == 1
        assert fx.price_increment == Price.from_str("0.00005")
        assert fx.price_precision == 5

    @pytest.mark.asyncio
    async def test_contract_id_to_instrument_id(self, mocker):
        # Arrange
        contract = IBTestStubs.contract(symbol="CLZ2", exchange="NYMEX")
        contract_details = IBTestStubs.contract_details("CLZ2")
        mocker.patch.object(
            self.provider._client,
            "qualifyContractsAsync",
            return_value=self.async_return_value([contract]),
        )
        mocker.patch.object(
            self.provider._client,
            "reqContractDetailsAsync",
            return_value=self.async_return_value([contract_details]),
        )

        # Act
        await self.provider.load(symbol="CLZ2", exchange="NYMEX")

        # Assert
        expected = {138979238: InstrumentId.from_str("CLZ2.NYMEX")}
        assert self.provider.contract_id_to_instrument_id == expected

    def test_filters(self):
        pass
예제 #18
0
def main(ib):
    from ib_insync import Stock, Forex, Index
    win_historical = sg.Window('Historical OHLC', layout)

    while True:  # Event Loop
        event, values = win_historical.Read()
        if event == 'Exit':
            #? commenting out "disconnect()" because any calling procedure would not want a child to disconnect it
            #ib.disconnect()
            logging.info("exit hit")
            win_historical.Close()
            break

        if event == 'Qualify':
            # Update the "output" element to be the value of "input" element
            win_historical.Element('_OUTPUT_').Update(values['_Symbol_'])
            if values['_SecType_'] == 'STK':
                contract = Stock(values['_Symbol_'], values['_Exchange_'],
                                 values['_Currency_'])
            if values['_SecType_'] == 'CASH':
                contract = Forex(values['_Symbol_'])
            if values['_SecType_'] == 'IND':
                contract = Index(values['_Symbol_'], values['_Exchange_'],
                                 values['_Currency_'])
            qual = ib.qualifyContracts(contract)
            logging.info(str(qual))

        if event == 'Fetch':
            strDuration = str(values['_DurStr1_']) + ' ' + str(
                values['_DurStr2_'])
            strBarSize = str(values['_BarSize_'])
            strWhatToShow = str(values['_WhatToShow_'])
            logging.info('strDuration:%s , strBarSize: %s , strWhatToShow: %s',
                         strDuration, strBarSize, strWhatToShow)
            barData = ib.reqHistoricalData(contract, '', strDuration,
                                           strBarSize, strWhatToShow, 1, 1,
                                           False)
            listData = [[
                item.date.strftime("%Y%m%d, %H:%M:%S"), item.open, item.high,
                item.low, item.close, item.volume, item.barCount, item.average
            ] for item in barData]
            dfStockData = pd.DataFrame(listData)
            if dfStockData.shape[1] == 8 and dfStockData.shape[0] > 0:
                logging.info('dfStockData sample: %s', dfStockData.head(3))
                dfStockData.columns = [
                    'date', 'open', 'high', 'low', 'close', 'volume',
                    'barCount', 'average'
                ]
                relist = dfStockData.values.tolist()
                win_historical.Element('sgtable').Update(values=relist,
                                                         num_rows=25,
                                                         visible=True)
        if event == 'Download':
            #check if the DatFrame is minimally populated or not.
            #if populated:
            if dfStockData.shape[1] == 8 and dfStockData.shape[0] > 0:
                file_name = sg.PopupGetFile(
                    'Please enter filename to save (if file exists, it will be overwritten): ',
                    save_as=True)
                fileTarget = open(file_name, 'w+')
                dfStockData.to_csv(fileTarget)
                fileTarget.close()
                sg.Popup("File saved.")
            #if NOT populated
            else:
                sg.Popup("Please fetch some data before trying to save it.")
    def parse_contract(ticker):
        """
        Backtrader contract specification (https://www.backtrader.com/docu/live/ib/ib.html):

        TICKER # Stock type and SMART exchange

        TICKER-STK # Stock and SMART exchange

        TICKER-STK-EXCHANGE # Stock

        TICKER-STK-EXCHANGE-CURRENCY # Stock

        TICKER-CFD # CFD and SMART exchange

        TICKER-CFD-EXCHANGE # CFD

        TICKER-CDF-EXCHANGE-CURRENCY # Stock

        TICKER-IND-EXCHANGE # Index

        TICKER-IND-EXCHANGE-CURRENCY # Index

        TICKER-YYYYMM-EXCHANGE # Future

        TICKER-YYYYMM-EXCHANGE-CURRENCY # Future

        TICKER-YYYYMM-EXCHANGE-CURRENCY-MULT # Future

        TICKER-FUT-EXCHANGE-CURRENCY-YYYYMM-MULT # Future

        TICKER-YYYYMM-EXCHANGE-CURRENCY-STRIKE-RIGHT # FOP

        TICKER-YYYYMM-EXCHANGE-CURRENCY-STRIKE-RIGHT-MULT # FOP

        TICKER-FOP-EXCHANGE-CURRENCY-YYYYMM-STRIKE-RIGHT # FOP

        TICKER-FOP-EXCHANGE-CURRENCY-YYYYMM-STRIKE-RIGHT-MULT # FOP

        CUR1.CUR2-CASH-IDEALPRO # Forex

        TICKER-YYYYMMDD-EXCHANGE-CURRENCY-STRIKE-RIGHT # OPT

        TICKER-YYYYMMDD-EXCHANGE-CURRENCY-STRIKE-RIGHT-MULT # OPT

        TICKER-OPT-EXCHANGE-CURRENCY-YYYYMMDD-STRIKE-RIGHT # OPT

        TICKER-OPT-EXCHANGE-CURRENCY-YYYYMMDD-STRIKE-RIGHT-MULT # OPT

        :return: 
        """
        contract_type, symbol, exchange, currency, expire, multiplier = \
            AsyncIBDataProvider.exctract_symbol(ticker)

        if contract_type == 'FX':
            return Forex(pair=symbol)
        if contract_type == 'IND':
            return Index(symbol, exchange, currency)
        if contract_type == 'FUT':
            return Future(symbol,
                          expire,
                          exchange,
                          currency=currency,
                          multiplier=multiplier)
        else:
            return Stock(symbol, exchange, currency)
예제 #20
0
def currency_exchange(request, currencies='EURUSD'):
    # print(currencies)
    ss1 = 'ss1'
    ss2 = 'ss2'
    ss3 = 'ss3'
    ss4 = 'ss4'
    ss5 = 'ss5'
    ss6 = 'ss6'
    ss7 = 'ss7'
    ss8 = 'ss8'
    ss9 = 'ss9'
    df = None
    is_error = 0
    try:
        loop = asyncio.get_event_loop_policy().new_event_loop()
        asyncio.set_event_loop(loop)
        ib_server = 'twoprojectsib1_tws_1'
        ib_port = 4003
        if settings.DEBUG:
            ib_server = '127.0.0.1'
            ib_port = 4002
        ib_ = IB()
        ci = randint(0, 100000)
        ib_.connect(ib_server, ib_port, clientId=ci)
        # print('ib_')
        # print(ib_)
        # print('ib_')
        ss1 = str(ib_)
    except Exception as e:
        ss1 = "Error connecting to: " + ib_server + ":" + str(ib_port)
        ss2 = e
        is_error = 1

    try:
        c = Forex(currencies)
        bars = ib_.reqHistoricalData(c,
                                     endDateTime='',
                                     durationStr='1 D',
                                     barSizeSetting='1 min',
                                     whatToShow='MIDPOINT',
                                     useRTH=True)
        # print(bars)
        ss3 = 'good 3'
        df = util.df(bars)
        # print(df[['date', 'open', 'high', 'low', 'close']])
        ss4 = 'good 4'
        df = df.sort_values(by=['date'], ascending=False)
        ss5 = 'good 5'

        ib_.disconnect()
        del ib_

        ss6 = 'good 6'
    except Exception as e2:
        ss7 = e2
        is_error = 1

    context = {
        'df':
        df,
        'ss1':
        ss1,
        'ss2':
        ss2,
        'ss3':
        ss3,
        'ss4':
        ss4,
        'ss5':
        ss5,
        'ss6':
        ss6,
        'ss7':
        ss7,
        'ss8':
        ss8,
        'ss9':
        ss9,
        'is_error':
        is_error,
        'currencies':
        currencies,
        'title':
        'Currency Exchange',
        'cur_list': [
            'GBPUSD', 'GBPZAR', 'HKDJPY', 'KRWAUD', 'KRWCAD', 'KRWCHF',
            'KRWEUR', 'KRWGBP', 'KRWHKD', 'KRWJPY', 'KRWUSD', 'MXNJPY',
            'NOKJPY', 'NOKSEK', 'NZDCAD', 'NZDCHF', 'NZDJPY', 'NZDUSD',
            'SEKJPY', 'SGDCNH', 'SGDJPY', 'TRYJPY', 'USDCAD', 'USDCHF',
            'USDCNH', 'USDCZK', 'USDDKK', 'USDHKD', 'USDHUF', 'USDILS',
            'USDJPY', 'USDKRW', 'USDMXN', 'USDNOK', 'USDPLN', 'USDRUB',
            'USDSEK', 'USDSGD', 'USDTRY', 'USDZAR', 'ZARJPY', 'EURPLN',
            'EURRUB', 'EURSEK', 'EURSGD', 'EURTRY', 'EURUSD', 'EURZAR',
            'GBPAUD', 'GBPCAD', 'GBPCHF', 'GBPCNH', 'GBPCZK', 'GBPDKK',
            'GBPHKD', 'GBPHUF', 'GBPJPY', 'GBPMXN', 'GBPNOK', 'GBPNZD',
            'GBPPLN', 'GBPSEK', 'GBPSGD', 'GBPTRY', 'GBPUSD', 'GBPZAR',
            'HKDJPY', 'KRWAUD', 'KRWCAD', 'KRWCHF', 'KRWEUR', 'KRWGBP',
            'KRWHKD', 'KRWJPY', 'KRWUSD', 'MXNJPY', 'NOKJPY', 'NOKSEK',
            'NZDCAD', 'NZDCHF', 'NZDJPY', 'NZDUSD', 'SEKJPY', 'SGDCNH',
            'SGDJPY', 'TRYJPY', 'USDCAD', 'USDCHF', 'USDCNH', 'USDCZK',
            'USDDKK', 'USDHKD', 'USDHUF', 'USDILS', 'USDJPY', 'USDKRW',
            'USDMXN', 'USDNOK', 'USDPLN', 'USDRUB', 'USDSEK', 'USDSGD',
            'USDTRY', 'USDZAR', 'ZARJPY'
        ]
    }
    return render(request, 'trades/currency_exchange.html', context)