Status order always margin
-
Hi all,
I am Eduardo and I am starting with backtrader (sorry for my writing my english is poor).
My doubt is conceptual, I always get status order margin however, in my strategy I set the cash to 10000 and I plot cash and the value and they are positives (final 22544,55), you can see in the images.
The code is simple, a crossover the SMA of 50 over SMA 100 and only take long positions. The data is BTCUSDT with a time frame four hours downloaded from binance future.
I can test by my records that no order is completed, you can see the next image:
My full code is:
from backtrader import order, position from backtrader_plotting import Bokeh from backtrader_plotting.schemes import Tradimo, Blackly import backtrader as bt import backtrader.feeds as btfeeds from backtrader.strategies import * import pandas as pd import quantstats import datetime as dt import warnings warnings.filterwarnings('ignore') class MAcrossover(bt.Strategy): params = (('pfast',50),('pslow',100)) def log(self, txt): dt = self.datas[0].datetime.datetime() print(f'{dt}, {txt}') def __init__(self): self.dataclose = self.datas[0].close self.order = None self.slow_sma = bt.indicators.SMA(self.dataclose, period=self.params.pslow) self.fast_sma = bt.indicators.SMA(self.dataclose, period=self.params.pfast) self.crossover = bt.indicators.CrossOver(self.fast_sma, self.slow_sma) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: if order.status == order.Submitted: self.log(f'{order.status}: Order Submitted') elif order.status == order.Accepted: self.log(f'{order.status}: Order Accepted') return if order.status in [order.Completed]: if order.isbuy(): self.log(f'BUY EXECUTED, Price: {self.order.executed.price:2f}, Cost: {self.order.executed.value:2f}, Comm {self.order.executed.comm:2f}') elif order.status in [order.Canceled, order.Margin, order.Rejected]: if order.status == order.Canceled: self.log(f'{order.status}: Order Canceled') elif order.status == order.Margin: self.log(f'{order.status}: Order Margin') elif order.status == order.Rejected: self.log(f'{order.status}: Order Rejected') self.order = None def next(self): self.log(f'Close: {self.dataclose[0]}') if self.order: return if not self.position: if self.crossover == 1: self.log(f'BUY CREATE {self.dataclose[0]:2f}') self.order = self.buy() print(f'LONG ENTRY ----------------------------------------\n{self.order}\n---------------------------------------------------') elif self.crossover == -1: self.log(f'CLOSE CREATE {self.dataclose[0]:2f}') self.order = self.close() print(f'LONG EXIT ----------------------------------------\n{self.order}\n---------------------------------------------------') if __name__ == '__main__': cerebro = bt.Cerebro() nombre = 'historico_BTCUSDT_4h' cash = 10000.0 cerebro.broker.setcash(cash) data = btfeeds.GenericCSVData( dataname=f'/home/eduardo/Qsync/trading/data/historicos_en_un_solo_archivo/{nombre}.csv', fromdate=dt.datetime(2020, 1, 1), todate=dt.datetime(2021, 10, 1), headers=True, separator=',', nullvalue=0.0, dtformat=('%Y-%m-%d %H:%M:%S'), datetime=0, open=1, high=2, low=3, close=4, volume=5, openinterest=-1, timeframe = bt.TimeFrame.Minutes, compression = 4*60, ) cerebro.adddata(data) cerebro.addstrategy(MAcrossover) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) results = cerebro.run() b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo()) cerebro.plot(b) print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
Any suggestion or help is welcome thank you very much in advance.
-
@eduardo-romero-lópez order.Margin status usually indicates there is not enough cash in your broker account for given order.
If your starting cash amount was only 10000 and the close price is 39358.4 - you can't afford to purchase even a single lot - resulting in order.Margin status.
-
thank you very much @vladisld. I understand it now, I was not taking into account the price of the asset and I was just thinking that I had cash to buy it.
-
I have changed the cash to 1,000,000 and it works.