def OF(): OI = Market( data_path="data/%s_Candlestick_4_Hour_BID_01.08.2018-30.11.2018.csv" % Om) Oa = Record() Oo = OrderManager(market=OI, record=Oa) OS = SureFireTrader(orderManager=Oo) OP = [20, 25, 30] OH = ['BUY', 'SELL'] Oy = [2, 3, 4] Oc = 12 OR = ConstantAgent(states=Og(type='float', shape=(Oc, Oc, 4)), actions=Og(SLTP_pips=Og(type='int', num_actions=OQ(OP)), start_order_type=Og(type='int', num_actions=OQ(OH)), max_level_limit=Og(type='int', num_actions=OQ(Oy))), action_values={ 'SLTP_pips': 0, 'max_level_limit': 0, 'start_order_type': 0 }) if not Ol.exists("save_model/constant/trades"): Op("save_model/constant/trades") if not Ol.exists('save_model/constant/0000'): Op('save_model/constant/0000') OR.save_model('save_model/constant/0000/model') OM = [] OW = [] OL = [] Os = 0 OX = 0 OB = OY OK = 12 Oa.reset() Oo.reset() OI.reset(start_index=Oc) OD = tqdm() while (OI.next()): OD.update(1) Oo.orders_check() OJ, Oz = OS.status_check() Oj = OI.get_ohlc(size=Oc) Ok = OI.get_indicators(size=Oc) O, H, L, C = gaf_encode(Oj['Open']), gaf_encode( Oj['High']), gaf_encode(Oj['Low']), gaf_encode(Oj['Close']) Or = On((O, H, L, C), axis=-1) if OJ == 'TRADE_OVER': if OI.get_current_index() > Oc: Of = (Oa.get_net_profit() - OW[-1]) / OI.get_pip() Ov = 1.0 - 0.1 * OQ(Oz) if Of > 0: Ou = Of * Ov else: if OQ(Oz) == 0: Ou = 0 else: Ou = -Ow(Oz[0]['TP'] - Oz[0]['price']) / OI.get_pip() if OI.get_current_index( ) >= OI.get_data_length() - OK * Oy[-1]: OB = OU OR.observe(reward=Ou, terminal=OB) OL.append(Ou) if OB == OU: OD.close() OM.append(OL) break OT = OR.act(Or) OE = OP[OT['SLTP_pips']] * 2 OG = OP[OT['SLTP_pips']] OS.set_max_level(Oy[OT['max_level_limit']]) Oq = OH[OT['start_order_type']] OS.new_trade(SL_pip=OE, TP_pip=OG, start_order_type=Oq) OX += 1 Os = 0 Ot("NewTradeStarted: current net profit=%f (price@%f)" % (Oa.get_net_profit(), OI.get_market_price())) elif OJ == 'ADD_ORDER': OA = OS.get_orders_detail()[-1] if OA['order_type'] == 'BUY': Oi = OA['price'] - OI.get_pip(OG) elif OA['order_type'] == 'SELL': Oi = OA['price'] + OI.get_pip(OG) OS.add_reverse_order(price=Oi, SL_pip=OE, TP_pip=OG) Os = 0 elif OJ == 'ERROR': Ox("SureFireError: order issues...") elif OJ == 'NONE': Os += 1 if Os >= OK: Of = (Oa.get_net_profit() - OW[-1]) / OI.get_pip() Ov = 1.0 - 0.1 * OQ(Oz) if Of > 0: Ou = Of * Ov else: if OQ(Oz) == 0: Ou = 0 else: Ou = -Ow(Oz[0]['TP'] - Oz[0]['price']) / OI.get_pip() if OI.get_current_index( ) >= OI.get_data_length() - OK * Oy[-1]: OB = OU OR.observe(reward=Ou, terminal=OB) OL.append(Ou) if OB == OU: OD.close() OM.append(OL) break OT = OR.act(Or) OE = OP[OT['SLTP_pips']] * 2 OG = OP[OT['SLTP_pips']] OS.set_max_level(Oy[OT['max_level_limit']]) Oq = OH[OT['start_order_type']] OS.new_trade(SL_pip=OE, TP_pip=OG, start_order_type=Oq) Os = 0 Ot("NewTradeStarted: current net profit=%f (price@%f)" % (Oa.get_net_profit(), OI.get_market_price())) OW.append(Oa.get_net_profit()) with OV('save_model/constant/trades/episode_0000.pkl', 'wb') as f: ON(Oa.get_history(), f, protocol=-1) with OV('save_model/constant/trades/profit_history.pkl', 'wb') as f: ON(OW, f, protocol=-1) with OV('save_model/constant/trades/reward_history.pkl', 'wb') as f: ON(OM, f, protocol=-1) Oa.show_details()
def main(): theMarket = Market( data_path="data/%s_Candlestick_4_Hour_BID_01.08.2018-30.11.2018.csv" % CURRENCY_PAIR) #, indicators={'ADX': 12}) MyRecord = Record() MyOrderManager = OrderManager(market=theMarket, record=MyRecord) MyTrader = SureFireTrader(orderManager=MyOrderManager) SLTP_pips = [20, 25, 30] start_order_type = ['BUY', 'SELL'] max_level_limit = [2, 3, 4] window_size = 12 # Create a RL agent with open("config/%s.json" % AGENT_METHOD, 'r') as fp: agent_config = json.load(fp=fp) with open("config/conv2d.json", 'r') as fp: network_config = json.load(fp=fp) agent = Agent.from_spec( spec=agent_config, kwargs=dict( states=dict(type='float', shape=(window_size, window_size, 4)), #[Open, High, Low, Close] actions=dict( SLTP_pips=dict(type='int', num_actions=len(SLTP_pips)), #[20,25,30] start_order_type=dict( type='int', num_actions=len(start_order_type)), #['BUY','SELL'] max_level_limit=dict( type='int', num_actions=len(max_level_limit)) #[2,3,4,5] ), network=network_config)) if not os.path.exists("save_model/%s/trades" % AGENT_METHOD): os.makedirs("save_model/%s/trades" % AGENT_METHOD) reward_history = [] for episode in trange(100 + 1, ascii=True): profit_history = [] this_reward_history = [] idle_count = 0 round_count = 0 episode_end = False max_idle_limit = 12 #future action MyRecord.reset() MyOrderManager.reset() theMarket.reset(start_index=window_size) pbar = tqdm() while (theMarket.next()): #main loop, essential pbar.update(1) # simple-GUI ################### ROUTINES ################### MyOrderManager.orders_check() #routine, after market.next trade_status, other_detail = MyTrader.status_check( ) #routine, after orders_check ################################################ ################### GET STATE ################## ohlc = theMarket.get_ohlc(size=window_size) indicators = theMarket.get_indicators(size=window_size) O, H, L, C = gaf_encode(ohlc['Open']), gaf_encode(ohlc['High']), \ gaf_encode(ohlc['Low']),gaf_encode(ohlc['Close']) #ADX = gaf_encode(indicators['ADX']) state = np.stack((O, H, L, C), axis=-1) ################################################ ################## TAKE ACTION ################# if trade_status == 'TRADE_OVER': ############ GET REWARD & TRAIN ################ if theMarket.get_current_index() > window_size: ''' profit = sum(round(order['profit'],5) for order in other_detail if order['profit']>0) loss = sum(round(order['profit'],5) for order in other_detail if order['profit']<0) this_profit_factor = MyRecord.get_profit_factor() this_trade_length = len(MyRecord.get_history()) reward = this_profit_factor*np.sqrt(this_trade_length)#SQN ''' raw_reward = (MyRecord.get_net_profit() - profit_history[-1]) / theMarket.get_pip() penalty = 1.0 - 0.1 * len(other_detail) if raw_reward > 0: reward = raw_reward * penalty else: if len(other_detail) == 0: reward = 0 else: reward = -np.abs(other_detail[0]['TP'] - other_detail[0]['price'] ) / theMarket.get_pip() if theMarket.get_current_index( ) >= theMarket.get_data_length( ) - max_idle_limit * max_level_limit[-1]: episode_end = True agent.observe( reward=reward, terminal=episode_end ) # Add experience, agent automatically updates model according to batch size this_reward_history.append(reward) if episode_end == True: if episode % 100 == 0: this_dir = 'save_model/%s/%04d' % (AGENT_METHOD, episode) if not os.path.exists(this_dir): os.makedirs(this_dir) agent.save_model(this_dir + '/model') pbar.close() reward_history.append(this_reward_history) with open( 'save_model/%s/trades/episode_%04d.pkl' % (AGENT_METHOD, episode), 'wb') as f: pickle.dump(MyRecord.get_history(), f, protocol=-1) break action = agent.act(state) # Get prediction from agent, execute SL_pip = SLTP_pips[action['SLTP_pips']] * 2 TP_pip = SLTP_pips[action['SLTP_pips']] MyTrader.set_max_level( max_level_limit[action['max_level_limit']]) first_order_type = start_order_type[action['start_order_type']] ################################################ MyTrader.new_trade(SL_pip=SL_pip, TP_pip=TP_pip, start_order_type=first_order_type) round_count += 1 idle_count = 0 logging.info( "NewTradeStarted: current net profit=%f (price@%f)" % (MyRecord.get_net_profit(), theMarket.get_market_price())) elif trade_status == 'ADD_ORDER': last_order = MyTrader.get_orders_detail()[-1] if last_order['order_type'] == 'BUY': price = last_order['price'] - theMarket.get_pip(TP_pip) elif last_order['order_type'] == 'SELL': price = last_order['price'] + theMarket.get_pip(TP_pip) MyTrader.add_reverse_order(price=price, SL_pip=SL_pip, TP_pip=TP_pip) idle_count = 0 elif trade_status == 'ERROR': logging.warning("SureFireError: order issues...") elif trade_status == 'NONE': idle_count += 1 if idle_count >= max_idle_limit: ############ GET REWARD & TRAIN ################ ''' profit = sum(round(order['profit'],5) for order in other_detail if order['profit']>0) loss = sum(round(order['profit'],5) for order in other_detail if order['profit']<0) this_profit_factor = MyRecord.get_profit_factor() this_trade_length = len(MyRecord.get_history()) reward = this_profit_factor*np.sqrt(this_trade_length)#SQN ''' raw_reward = (MyRecord.get_net_profit() - profit_history[-1]) / theMarket.get_pip() penalty = 1.0 - 0.1 * len(other_detail) if raw_reward > 0: reward = raw_reward * penalty else: if len(other_detail) == 0: reward = 0 else: reward = -np.abs(other_detail[0]['TP'] - other_detail[0]['price'] ) / theMarket.get_pip() if theMarket.get_current_index( ) >= theMarket.get_data_length( ) - max_idle_limit * max_level_limit[-1]: episode_end = True agent.observe( reward=reward, terminal=episode_end ) # Add experience, agent automatically updates model according to batch size this_reward_history.append(reward) if episode_end == True: if episode % 100 == 0: this_dir = 'save_model/%s/%04d' % (AGENT_METHOD, episode) if not os.path.exists(this_dir): os.makedirs(this_dir) agent.save_model(this_dir + '/model') pbar.close() reward_history.append(this_reward_history) with open( 'save_model/%s/trades/episode_%04d.pkl' % (AGENT_METHOD, episode), 'wb') as f: pickle.dump(MyRecord.get_history(), f, protocol=-1) break action = agent.act( state) # Get prediction from agent, execute SL_pip = SLTP_pips[action['SLTP_pips']] * 2 TP_pip = SLTP_pips[action['SLTP_pips']] MyTrader.set_max_level( max_level_limit[action['max_level_limit']]) first_order_type = start_order_type[ action['start_order_type']] ################################################ MyTrader.new_trade(SL_pip=SL_pip, TP_pip=TP_pip, start_order_type=first_order_type) idle_count = 0 logging.info( "NewTradeStarted: current net profit=%f (price@%f)" % (MyRecord.get_net_profit(), theMarket.get_market_price())) ################################################ profit_history.append(MyRecord.get_net_profit()) #for plotting #MyRecord.show_details() #print("Rounds of Tradings: %d\n"%round_count) #with open('save_model/%s/trades/profit_history.pkl'%AGENT_METHOD, 'wb') as f: #pickle.dump(profit_history,f,protocol=-1) with open('save_model/%s/trades/reward_history.pkl' % AGENT_METHOD, 'wb') as f: pickle.dump(reward_history, f, protocol=-1)
def Ql(): Qv=Market(data_path="data/%s_Candlestick_4_Hour_BID_01.08.2018-30.11.2018.csv"%QX) QR=Record() QH=OrderManager(market=Qv,record=QR) QI=SureFireTrader(orderManager=QH) Qd=[30,35,40,45,50] QP=['BUY','SELL'] Qw=[1,2,3,4,5,6,7] QN=24 with tX("config/%s.json"%Qt,'r')as fp: QD=QC(fp=fp) with tX("config/conv2d.json",'r')as fp: Qc=QC(fp=fp) QF=Qo(spec=QD,kwargs=tv(states=tv(type='float',shape=(QN,QN,4)),actions=tv(SLTP_pips=tv(type='int',num_actions=tR(Qd)),start_order_type=tv(type='int',num_actions=tR(QP)),max_level_limit=tv(type='int',num_actions=tR(Qw))),network=Qc)) if not QS.exists("save_model/%s/trades"%Qt): Qx("save_model/%s/trades"%Qt) QY=[] for Qi in Qz(100+1,ascii=tH): Qq=[] Qm=[] QA=0 QV=0 QB=tI QK=12 QR.reset() QH.reset() Qv.reset(start_index=QN) Qj=tqdm() while(Qv.next()): Qj.update(1) QH.orders_check() Qu,QE=QI.status_check() QO=Qv.get_ohlc(size=QN) Qf=Qv.get_indicators(size=QN) O,H,L,C=gaf_encode(QO['Open']),gaf_encode(QO['High']), gaf_encode(QO['Low']),gaf_encode(QO['Close']) Qh=Qs((O,H,L,C),axis=-1) if Qu=='TRADE_OVER': if Qv.get_current_index()>QN: QJ=(QR.get_net_profit()-Qq[-1])/Qv.get_pip() Qr=1.0-0.1*tR(QE) if QJ>0: Qa=QJ*Qr else: if tR(QE)==0: Qa=0 else: Qa=-QM(QE[0]['TP']-QE[0]['price'])/Qv.get_pip() if Qv.get_current_index()>=Qv.get_data_length()-QK*Qw[-1]: QB=tH QF.observe(reward=Qa,terminal=QB) Qm.append(Qa) if QB==tH: if Qi%100==0: QT='save_model/%s/%04d'%(Qt,Qi) if not QS.exists(QT): Qx(QT) QF.save_model(QT+'/model') Qj.close() QY.append(Qm) with tX('save_model/%s/trades/episode_%04d.pkl'%(Qt,Qi),'wb')as f: tQ(QR.get_history(),f,protocol=-1) break QG=QF.act(Qh) Qe=Qd[QG['SLTP_pips']]*2 Qy=Qd[QG['SLTP_pips']] QI.set_max_level(Qw[QG['max_level_limit']]) Qk=QP[QG['start_order_type']] QI.new_trade(SL_pip=Qe,TP_pip=Qy,start_order_type=Qk) QV+=1 QA=0 Qb("NewTradeStarted: current net profit=%f (price@%f)"%(QR.get_net_profit(),Qv.get_market_price())) elif Qu=='ADD_ORDER': QW=QI.get_orders_detail()[-1] if QW['order_type']=='BUY': Qn=QW['price']-Qv.get_pip(Qy) elif QW['order_type']=='SELL': Qn=QW['price']+Qv.get_pip(Qy) QI.add_reverse_order(price=Qn,SL_pip=Qe,TP_pip=Qy) QA=0 elif Qu=='ERROR': Qp("SureFireError: order issues...") elif Qu=='NONE': QA+=1 if QA>=QK: QJ=(QR.get_net_profit()-Qq[-1])/Qv.get_pip() Qr=1.0-0.1*tR(QE) if QJ>0: Qa=QJ*Qr else: if tR(QE)==0: Qa=0 else: Qa=-QM(QE[0]['TP']-QE[0]['price'])/Qv.get_pip() if Qv.get_current_index()>=Qv.get_data_length()-QK*Qw[-1]: QB=tH QF.observe(reward=Qa,terminal=QB) Qm.append(Qa) if QB==tH: if Qi%100==0: QT='save_model/%s/%04d'%(Qt,Qi) if not QS.exists(QT): Qx(QT) QF.save_model(QT+'/model') Qj.close() QY.append(Qm) with tX('save_model/%s/trades/episode_%04d.pkl'%(Qt,Qi),'wb')as f: tQ(QR.get_history(),f,protocol=-1) break QG=QF.act(Qh) Qe=Qd[QG['SLTP_pips']]*2 Qy=Qd[QG['SLTP_pips']] QI.set_max_level(Qw[QG['max_level_limit']]) Qk=QP[QG['start_order_type']] QI.new_trade(SL_pip=Qe,TP_pip=Qy,start_order_type=Qk) QA=0 Qb("NewTradeStarted: current net profit=%f (price@%f)"%(QR.get_net_profit(),Qv.get_market_price())) Qq.append(QR.get_net_profit()) with tX('save_model/%s/trades/reward_history.pkl'%Qt,'wb')as f: tQ(QY,f,protocol=-1)