stellathecat / github

0 stars 0 forks source link

martingale.R #2

Open stellathecat opened 7 years ago

stellathecat commented 7 years ago

Hi Vladi!

At the moment, we have the same increments for every trade. But there could be another way: Increase positions with a smaller interval (for example every 0.0001), but take profit with a large interval (0.0010). It's similar to a 0.0010/0.0010 setting, only that there are more opportunities to trade (and take-profit), plus higher transaction costs.

See pic below. Can you modify the script (martingale.R) such that there are two increments?

kurnosovv commented 7 years ago

Need some clarifications, the idea is not clear to me. As far as I understand, in this case in stack I should also keep the price at which the bought stock should be sold, or sold stock should be bought. If price movements are very small (for example +-0.0001 for a long period), what will we have in the stack? Multiple similar records in the stack, both "buy" and "sell"? What will happen if we reach the price of closing such multiple positions - will we close all of them? And maybe we should also open new position in the opposite direction in such case?

stellathecat commented 7 years ago

Hi Vladi! Ok sorry :-) First the explanation of the picture: The horizontal bars are trades. Let's assume we have zero position at the beginning of the day.

You see that my setting sells (red) at each 0.0001 increment. It would be the same as if we would set increment to 0.0001 in the script. In the stack (I think) nothing would change. However, as opposed to the script, my setting waits until a 0.0010 increment is reached (for profit-taking, or taking the position out of stock).

For example, the first sell is at 1.0950 at 1:30 am. In the script, the next buy would then be 1.0949. However, I wait for 1.0940 (0.0010 increment). You see that there was a sell at 7:30 am at 1.0955, the next buy would then be 1.0945, which was reached at 10:00 am. There is always a 0.0010 difference between (last) red sell and (next) blue buy.

The same works then in reverse for the other side. If the price would have moved down (for example here from the beginning of the day), the buy orders would have been 1.0944, then 1.0943, 1.0942, ... but the next sell (if buy executed) 1.0954, 1.0953, 1.0952, ...

So I would say the only thing that needs to be changed is adding another variable: the increment for profit-taking (-> out of stack) which is not the same as the increment for building of positions (-> in stack).

Good night! :-)

kurnosovv commented 7 years ago

Yep, now it is more clear to me. I introduces one more increment variable, and you have two function arguments instead of one related to increment now - increment_position and increment_profit. The main issue is to implement properly the behavior that you described. Please check the new script, if I did it correctly. I am not sure when we have a big jump in the price, and should close many open positions at once. In this case I simplify things, and consider that every position is closed when the observed price differs exactly by +- increment (0.0010) from opening price (which we save to the the stack), so the profit from one position is always fixed (=betsize*increment_profit). I believe we had the same situation with the previous script. Also, if the price movement was very strong and we closed all open positions, then we may open new one (to the opposite side), and only one. Do not know if this is correct assumption of what we should do. And for the case when we observe movement of price into one direction and only open new positions, I left the previous code. It will keep the discretion which we had earlier (but earlier we used increment_position=0.0010, so maybe with increment_position=0.0001 it will be not noticeable). I would suggest you to test this new script and tell me what you think. I did some testing but still not sure that it is working as you supposed to be.

stellathecat commented 7 years ago

Hi Vladi!

Check: martingale(test['2016-05-04'],'2016-05','2016-06',0.0001,0.0010,100000,2,2,0)

There is: 2016-05-04 00:22:00 buy at 1.0973 2016-05-04 00:38:00 sell at 1.0974

However, after the last buy, the next sell should be 0.0010 away, so 1.0983 (1.0973+0.0010)

kurnosovv commented 7 years ago

Hi! Yes, you are absolutely correct, I saw the mistake in my implementation and corrected it. Please check the updated version of the script.

stellathecat commented 7 years ago

Hi Vladi! Thanks! There is one minor thing where I am not sure what to do. Suppose I want to plot the trades as in the picture here. I had previously used "level" as variable (see my changes in the script: data$at <- NA). But now it seems that sometimes (not always) I need "level + increment". Do you have a better idea for doing this?

rplotxxx

asd=martingale(test['2016-05-04'],'2016-05','2016-06',0.0001,0.0010,100000,2,2,0) asd$B=ifelse(diff(asd$outstanding)>0,asd$at,NA) asd$S=ifelse(diff(asd$outstanding)<0,asd$at,NA) plot.zoo((asd[,4]+asd[,8])/2, main='EUR/CHF 2016-05-04', ylab='', xlab='') points(asd$B, pch='-', col='blue') points(asd$S, pch='-', col='red')

kurnosovv commented 7 years ago

Yeah, indeed there is some mess, cause now we have two levels - one for buy operations and one for sell operations, the they are quite different. In the code I keep only one variable for level, and do some additional verifications to see which level we should apply in current situation. Such approach does not let you to use this code for building such plot. And there is no point in adding one more level variable, the code will still be messy, and will have to think whuch level to use for plotting. Instead, I introduced the trade_history dataframe that saves info on all the trades. It is quite similar to trade_stack, but stack is used for adding/deleting trades, and with trade_history, I only add info and do not erase it. After the code for trading runs, you may use this history for building the plot. I added it to the plotting section. Pay attention that I do not use data$at column (commented it). But if you wish to have such column, and build the plot later, not in this function, then we may think how we may do it better. Using additional dataframe is good also in situations when we have multiple trades at the same moment of time - then we may see all of them on the graph.