def update_fx_prices(): """ Update FX prices stored in Arctic (Mongo) with interactive brokers prices (usually going back about a year) :return: Nothing """ mongo_db = mongoDb( ) # will use default database, host unles specified here log = logger("Update-FX-prices", mongo_db=mongo_db) ib_conn = connectionIB(log=log.setup( component="IB-connection")) # will use default port, host ibfxpricedata = ibFxPricesData(ib_conn, log=log.setup(component="ibFxPricesData")) arcticfxdata = arcticFxPricesData( mongo_db=mongo_db, log=log.setup(component="arcticFxPricesData")) list_of_codes_all = ibfxpricedata.get_list_of_fxcodes( ) # codes must be in .csv file /sysbrokers/IB/ibConfigSpotFx.csv log.msg("FX Codes: %s" % str(list_of_codes_all)) for fx_code in list_of_codes_all: log.label(currency_code=fx_code) new_fx_prices = ibfxpricedata.get_fx_prices( fx_code) # returns fxPrices object arcticfxdata.update_fx_prices(fx_code, new_fx_prices) ib_conn.disconnect()
def ib_conn(self): ib_conn = getattr(self, "_ib_conn", arg_not_supplied) if ib_conn is arg_not_supplied: ib_conn = connectionIB() self._ib_conn = ib_conn return ib_conn
def update_manual_check_fx_prices(fx_code): """ Update FX prices stored in Arctic (Mongo) with interactive brokers prices (usually going back about a year) :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-FX-prices", mongo_db=mongo_db) as log,\ connectionIB(log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob("ibFxPricesData arcticFxPricesData", ib_conn=ib_conn, mongo_db=mongo_db) list_of_codes_all = data.ib_fx_prices.get_list_of_fxcodes( ) # codes must be in .csv file /sysbrokers/IB/ibConfigSpotFx.csv if fx_code not in list_of_codes_all: print("\n\n\ %s is not an FX code (valid codes: %s) \n\n" % (fx_code, list_of_codes_all)) raise Exception() log.label(currency_code=fx_code) update_manual_check_fx_prices_for_code(fx_code, data) return success
def update_fx_prices(): """ Update FX prices stored in Arctic (Mongo) with interactive brokers prices (usually going back about a year) :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-FX-prices", mongo_db=mongo_db) as log,\ connectionIB(log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob("ibFxPricesData arcticFxPricesData", ib_conn=ib_conn, mongo_db=mongo_db) list_of_codes_all = data.ib_fx_prices.get_list_of_fxcodes( ) # codes must be in .csv file /sysbrokers/IB/ibConfigSpotFx.csv log.msg("FX Codes: %s" % str(list_of_codes_all)) for fx_code in list_of_codes_all: try: log.label(currency_code=fx_code) update_fx_prices_for_code(fx_code, data) except Exception as e: log.warn("Something went wrong with FX update %s" % e) return success
def update_historical_prices(): """ Do a daily update for futures contract prices, using IB historical data :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-Historical-prices", mongo_db=mongo_db) as log,\ connectionIB(mongo_db = mongo_db, log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob( "ibFuturesContractPriceData arcticFuturesContractPriceData \ arcticFuturesMultiplePricesData mongoFuturesContractData", mongo_db=mongo_db, log=log, ib_conn=ib_conn) list_of_codes_all = data.arctic_futures_multiple_prices.get_list_of_instruments( ) for instrument_code in list_of_codes_all: update_historical_prices_for_instrument( instrument_code, data, log=log.setup(instrument_code=instrument_code)) return success
def update_fx_prices(): """ Update FX prices stored in Arctic (Mongo) with interactive brokers prices (usually going back about a year) :return: Nothing """ # avoid unique ids conn = connectionIB(client=100) ibfxpricedata = ibFxPricesData(conn) arcticfxdata = arcticFxPricesData() list_of_codes_all = ibfxpricedata.get_list_of_fxcodes( ) # codes must be in .csv file /sysbrokers/IB/ibConfigSpotFx.csv print(list_of_codes_all) for fx_code in list_of_codes_all: print(fx_code) new_fx_prices = ibfxpricedata.get_fx_prices( fx_code) # returns fxPrices object if len(new_fx_prices) == 0: print("couldn't get any more data") continue old_fx_prices = arcticfxdata.get_fx_prices(fx_code) new_fx_prices = new_fx_prices[ new_fx_prices.index > old_fx_prices.index[-1]] if len(new_fx_prices) == 0: print("No new data found") continue # merge old and new print("Old:") print(old_fx_prices.tail(2)) print("New:") print(new_fx_prices.head(2)) fx_prices = pd.concat([old_fx_prices, new_fx_prices], axis=0) fx_prices = fx_prices.sort_index() # remove duplicates fx_prices = fx_prices[~fx_prices.index.duplicated(keep='first')] print("Merged") print(fx_prices.tail(5)) # write arcticfxdata.add_fx_prices(fx_code, fx_prices, ignore_duplication=True)
def update_fx_prices(): """ Update FX prices stored in Arctic (Mongo) with interactive brokers prices (usually going back about a year) :return: Nothing """ log = logger("Update-FX-prices") ib_conn = connectionIB(log=log.setup( component="IB-connection")) # will use default port, host mongo_db = mongoDb( ) # will use default database, host unles specified here ibfxpricedata = ibFxPricesData(ib_conn, mongo_db=mongo_db, log=log.setup(component="ibFxPricesData")) arcticfxdata = arcticFxPricesData( mongo_db=mongo_db, log=log.setup(component="arcticFxPricesData")) list_of_codes_all = ibfxpricedata.get_list_of_fxcodes( ) # codes must be in .csv file /sysbrokers/IB/ibConfigSpotFx.csv log.msg("FX Codes: %s" % str(list_of_codes_all)) for fx_code in list_of_codes_all: log.label(currency_code=fx_code) new_fx_prices = ibfxpricedata.get_fx_prices( fx_code) # returns fxPrices object if len(new_fx_prices) == 0: log.error("Error trying to get data for %s" % fx_code) continue old_fx_prices = arcticfxdata.get_fx_prices(fx_code) new_fx_prices = new_fx_prices[ new_fx_prices.index > old_fx_prices.index[-1]] if len(new_fx_prices) == 0: log.msg("No additional data for %s" % fx_code) continue fx_prices = pd.concat([old_fx_prices, new_fx_prices], axis=0) fx_prices = fx_prices.sort_index() # remove duplicates fx_prices = fx_prices[~fx_prices.index.duplicated(keep='first')] # write arcticfxdata.add_fx_prices(fx_code, fx_prices, ignore_duplication=True)
def update_account_values(): """ Do a daily update of accounting information Get the total account value from IB, and calculate the p&l since we last ran This calculation is done using a user specified handler, which can deal with eg multiple accounts if required Needs to know about any withdrawals. Does spike checking: large changes in account value are checked before writing If your strategy has very high risk you may wish to do this more frequently than daily :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-Account-Values", mongo_db=mongo_db) as log,\ connectionIB(mongo_db = mongo_db, log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob(mongo_db=mongo_db, log=log, ib_conn=ib_conn) capital_data = dataCapital(data) ## This assumes that each account only reports eithier in one currency or for each currency, i.e. no double counting total_account_value_in_base_currency = capital_data.get_ib_total_capital_value( ) log.msg("Broker account value is %f" % total_account_value_in_base_currency) # Update total capital try: new_capital = capital_data.total_capital_calculator.\ get_total_capital_with_new_broker_account_value(total_account_value_in_base_currency) except Exception as e: ## Problem, most likely spike log.critical( "Error %s whilst updating total capital; you may have to use update_capital_manual script or function" % e) return failure log.msg("New capital is %f" % new_capital) return success
def update_strategy_capital(): """ Allocate capital to different strategies :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-Strategy-Capital", mongo_db=mongo_db) as log,\ connectionIB(mongo_db = mongo_db, log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob(mongo_db = mongo_db, log = log, ib_conn = ib_conn) try: strategy_allocation(data) except Exception as e: ## Problem, will send email log.critical("Error %s whilst allocating strategy capital" % e) return success
def update_capital_manual(): """ Interactive session that allows you to manipulate capital manually :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-Capital-Manual", mongo_db=mongo_db) as log,\ connectionIB(mongo_db = mongo_db, log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob(mongo_db = mongo_db, log = log, ib_conn = ib_conn) data_capital = dataCapital(data) still_running = True while still_running: # display capital and get input user_option_int = print_capital_and_get_user_input(data_capital) if user_option_int==0: setup_initial_capital(data_capital) elif user_option_int==1: update_capital_from_ib(data_capital) elif user_option_int==2: adjust_capital_for_delta(data_capital) elif user_option_int==3: modify_any_value(data_capital) elif user_option_int==4: delete_capital_since_time(data_capital) elif user_option_int==919: delete_all_capital(data_capital) elif user_option_int==5: still_running=False break else: print("%d is not a valid option but was in list of possible options: check code" % str(user_option_int)) ## Back to top of while loop return success
def update_manual_check_historical_prices(instrument_code:str): """ Do a daily update for futures contract prices, using IB historical data If any 'spikes' are found, run manual checks :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-Historical-prices-manually", mongo_db=mongo_db) as log,\ connectionIB(mongo_db = mongo_db, log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob("ibFuturesContractPriceData arcticFuturesContractPriceData \ arcticFuturesMultiplePricesData mongoFuturesContractData", mongo_db = mongo_db, log = log, ib_conn = ib_conn) list_of_codes_all = data.arctic_futures_contract_price.get_instruments_with_price_data() if instrument_code not in list_of_codes_all: print("\n\n\ %s is not an instrument with price data \n\n" % instrument_code) raise Exception() update_historical_prices_with_checks_for_instrument(instrument_code, data, log=log.setup(instrument_code = instrument_code)) return success
def update_sampled_contracts(): """ Update the active contracts, according to what is available in IB for a given instrument These are stored in mongoDB The active contracts list is used to see what contracts have historical data sampled for It does not tell you what the current priced, forward, or carry contract are - that is in multiple prices (DRY) However we base the list of theoretical active contracts on the current priced, forward, and carry contracts We will end up adding to this list when we roll; this will change the current priced, forward, and carry contract When we add a new contract (because one has become available), we get the exact expiry date from IB and save this with the contract data. We do not sample contracts on the list when they have passed their expiry date Contracts are never deleted from the database We don't check IB for contracts; since we can't reverse engineer a YYYYMM identifier from a YYYYMMDD :returns: None """ with mongoDb() as mongo_db,\ logger("Update-Sampled_Contracts", mongo_db=mongo_db) as log,\ connectionIB(log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob("arcticFuturesMultiplePricesData ibFuturesContractPriceData\ mongoFuturesContractData mongoRollParametersData", mongo_db, ib_conn, log=log) list_of_codes_all = data.arctic_futures_multiple_prices.get_list_of_instruments() for instrument_code in ['CRUDE_W']: new_log = log.setup(instrument_code = instrument_code) update_active_contracts_for_instrument(instrument_code, data, log=new_log)
def update_account_values(): """ Do a daily update of accounting information Get the total account value from IB, and calculate the p&l since we last ran This calculation is done using a user specified handler, which can deal with eg multiple accounts if required Needs to know about any withdrawals. Does spike checking: large changes in account value are checked before writing Also get various other capital information accountValues accountSummary portfolio positions reqPnL pnl cancelPnL reqPnLSingle pnlSingle cancelPnLSingle All of this is passed to a single capital allocator function that calculates how much capital each strategy should be allocated and works out the p&l for each strategy This can be done in various ways, eg by instrument, by asset class, as a % of total account value ... allow each strategy to keep it's p&l, or redistribute What about margin? Might need to know 'in real time' what the margin is per strategy, if when using whatif trades need to check. However better doing this on a global basis for account If your strategy has very high risk you may wish to do this more frequently than daily :return: Nothing """ with mongoDb() as mongo_db,\ logger("Update-Historical-prices", mongo_db=mongo_db) as log,\ connectionIB(mongo_db = mongo_db, log=log.setup(component="IB-connection")) as ib_conn: data = dataBlob( "ibFuturesContractPriceData arcticFuturesContractPriceData \ arcticFuturesMultiplePricesData mongoFuturesContractData", mongo_db=mongo_db, log=log, ib_conn=ib_conn) currency_data = currencyData(data) values_across_accounts = data.ib_conn.broker_get_account_value_across_currency_across_accounts( ) ## This assumes that each account only reports eithier in one currency or for each currency, i.e. no double counting total_account_value_in_base_currency = currency_data.total_of_list_of_currency_values_in_base( values_across_accounts) return success