def processCashPositionFile(file, outputDir=get_current_path()): """ [String] cash or position file => [String] output file Convert an GuangFa cash or position file to cash or position file ready for Geneva reconciliation. """ # if isCashFile(file): # return processCashFile(file, outputDir) # elif isPositionFile(file): # return processPositionFile(file, outputDir) # else: # raise InvalidFileName(file) logger.info('processCashPositionFile(): {0}'.format(file)) if isCashFile(file): return writeCashFile('40006-D', createCashRecords(file), outputDir, getDateFromFilename(file)) elif isPositionFile(file): return writePositionFile('40006-D', createPositionRecords(file), outputDir, getDateFromFilename(file)) else: logger.debug('processCashPositionFile(): not a cash or position file: \ {0}'.format(file)) return ''
def testTradeRecords(self): records = list( createTradeRecords( join(get_current_path(), 'samples', 'trade1', 'DU1237908.Trades_TradeConfirmFlex.Sample.csv'))) self.assertEqual(len(records), 32) self.verifyTrade1(records[0]) self.verifyTrade2(records[30])
def testCash(self): records = createCashRecords( join(get_current_path(), 'samples', 'cash_IB.csv')) self.assertEqual(len(records), 3) self.assertAlmostEqual(records[0]['Quantity'], 29056) self.assertEqual(records[0]['Currency'], 'EUR') self.assertAlmostEqual(records[2]['Quantity'], 1091204.12) self.assertEqual(records[2]['Currency'], 'USD')
def testCreateCashRecords(self): records = createCashRecords(join(get_current_path(), 'samples', '8888802200cusfund_f20140129.txt')) self.assertEqual(len(records), 9) self.assertEqual('HKD', records[1]['Currency']) self.assertEqual(datetime(2014,1,29), records[1]['Date']) self.assertAlmostEqual(0, records[1]['Quantity']) self.assertEqual('USD', records[6]['Currency']) self.assertEqual(datetime(2014,1,29), records[6]['Date']) self.assertAlmostEqual(1026915.92, records[6]['Quantity'])
def testRecordGroups(self): """ After sorting, 7th and 8th records form a box position, therefore all records should be separated into 2 groups. """ groups = toRecordGroups(createTradeRecords(join(get_current_path(), 'samples', 'trade_henghua.xlsx'))) self.assertEqual(len(groups), 2) self.assertEqual(len(groups[0]), 7) self.assertEqual(len(groups[1]), 13) self.verifyTrade3(groups[0][6]) self.verifyTrade4(groups[1][0])
def testCreateTradeRecords(self): records = list(createTradeRecords(join(get_current_path(), 'samples', 'XXXtrddata_f20130607.txt'))) self.assertEqual(len(records), 19) self.verifyTradeRecord1(records[0]) # make sure sorting works self.assertAlmostEqual(3.83, records[1]['Price']) self.assertAlmostEqual(3.85, records[2]['Price']) self.assertAlmostEqual(3.86, records[3]['Price']) self.assertAlmostEqual(3.80, records[4]['Price'])
def processTradeFile(file, outputDir=get_current_path()): """ [String] trade file, [String] outputDir => [List] output file names read the trade file, convert it to trade records and write it to a list of output csv files, to be uploaded by Bloomberg. """ logger.info('processTradeFile(): {0}'.format(file)) return writeTradeFiles(toOpenCloseGroup(createTradeRecords(file)), outputDir, '40006-D', 'GF-QUANT', getDateFromFilename(file))
def _load_config(): """ Read the config file, convert it to a config object. The config file is supposed to be located in the same directory as the py files, and the default name is "config". Caution: uncaught exceptions will happen if the config files are missing or named incorrectly. """ cfg = configparser.ConfigParser() cfg.read(join(get_current_path(), 'ib.config')) return cfg
def testCreatePositionRecords(self): records = createPositionRecords(join(get_current_path(), 'samples', '8888802200holddata_f20140129.txt')) self.assertEqual(len(records), 15) self.assertEqual(datetime(2014,1,29), records[0]['Date']) self.assertEqual('SMH4 Comdty', records[0]['BloombergTicker']) self.assertEqual('USD', records[0]['Currency']) self.assertEqual(8, records[0]['Quantity']) self.assertEqual(datetime(2014,1,29), records[5]['Date']) self.assertEqual('S K4 Comdty', records[5]['BloombergTicker']) self.assertEqual('USD', records[5]['Currency']) self.assertEqual(-4, records[5]['Quantity'])
def testRecordGroups(self): """ After sorting, 6th and 7th records form a box position, therefore all records should be separated into 2 groups. """ groups = list(toOpenCloseGroup(createTradeRecords(join(get_current_path(), 'samples', '8888802200trddata_f20140131.txt')))) self.assertEqual(len(groups), 2) self.assertEqual(len(groups[0]), 1) # 1st group has 1 trade self.assertEqual(len(groups[1]), 5) # 2nd group has 5 trades self.verifyTradeRecord2(groups[0][0]) self.verifyTradeRecord3(groups[1][4])
def testCashRecords(self): records = createCashRecords(join(get_current_path(), 'samples', 'cash_henghua.xlsx')) self.assertEqual(len(records), 4) def getCurrency(record): return record['Currency'] sortedRecords = sorted(records, key=getCurrency) self.assertEqual(sortedRecords[0]['Currency'], 'EUR') self.assertAlmostEqual(sortedRecords[0]['Quantity'], 14879.55) self.assertEqual(sortedRecords[1]['Currency'], 'HKD') self.assertAlmostEqual(sortedRecords[1]['Quantity'], 4600520.48) self.assertEqual(sortedRecords[2]['Currency'], 'TWD') self.assertAlmostEqual(sortedRecords[2]['Quantity'], 17329.36) self.assertEqual(sortedRecords[3]['Currency'], 'USD') self.assertAlmostEqual(sortedRecords[3]['Quantity'], 264762.136)
def processCashPositionFile(file, outputDir=get_current_path()): """ [String] cash or position file => [String] output file Convert an IB cash or position file to cash or position file ready for Geneva reconciliation. The rule is: cash file name always starts with 'cash', position file name always starts with 'position'. """ logger.info('processCashPositionFile(): {0}'.format(file)) if isCashFile(file): return writeCashFile('40006-B', createCashRecords(file), outputDir, getDateFromFilename(file)) elif isPositionFile(file): return writePositionFile('40006-B', createPositionRecords(file), outputDir, getDateFromFilename(file)) else: logger.debug('processCashPositionFile(): not a cash or position file: \ {0}'.format(file)) return ''
if __name__ == '__main__': import logging.config logging.config.fileConfig('logging.config', disable_existing_loggers=False) import argparse parser = argparse.ArgumentParser() parser.add_argument('file', metavar='input file', type=str) parser.add_argument('--type', metavar='file type', choices=['t', 'pc'], default='pc') args = parser.parse_args() """ To run the program, put a trade/cash/position file in the local directory, then do: python ib.py <file_name> --type c (t for trade file , pc for position or trade file , default is 'pc') """ import sys if args.file == None: print('input file name is missing') sys.exit(1) elif args.type == 't': processTradeFile(join(get_current_path(), args.file)) else: processCashPositionFile(join(get_current_path(), args.file), get_current_path())
def testHolding(self): records = createPositionRecords( join(get_current_path(), 'samples', 'position_IB.csv')) self.assertEqual(len(records), 12) self.verifyPosition1(records[0]) self.verifyPosition2(records[11])
def testCreateTradeRecords2(self): records = list(createTradeRecords(join(get_current_path(), 'samples', '8888802200trddata_f20140131.txt'))) self.assertEqual(len(records), 6) self.verifyTradeRecord2(records[5])
def testTradeRecords(self): records = createTradeRecords(join(get_current_path(), 'samples', 'trade_henghua.xlsx')) self.assertEqual(len(records), 20) self.verifyTrade1(records[0]) self.verifyTrade2(records[19])
def testFileToRecords(self): records = tradefileToRecords(join(get_current_path(), 'samples', 'XXXtrddata_f20130603.txt')) self.assertEqual(len(records), 20) self.verifyFileRecord1(records[0]) self.verifyFileRecord2(records[19])
def testPositionRecords(self): records = createPositionRecords(join(get_current_path(), 'samples', 'position_henghua.xlsx')) self.assertEqual(len(records), 19) self.verifyPosition1(records[0]) self.verifyPosition2(records[17])